0

So I have a component that looks like this:

import React, { memo, useState } from "react";    
import styles from "./navigation.styles.scss";

const Navigation = ({ children }) => {

    const [toggle, toggleState] = useState(false);

    return (
        <>
            <div onClick={() => toggleState(!toggle)}>
                <p>Test</p>
            </div>
            {children}
            <style jsx>{styles}</style>
        </>
    );
};

export default memo(Navigation);

And then I have another component that looks like this:

import React, { memo, useState } from "react";    
import styles from "./container.styles.scss";

const Container = ({ children }) => {

    const [toggle, toggleState] = useState(false);

    return (
        <>
            <div className={toggle ? "dark-bg" : "dark-bg active"}>
                {children}
            </div>
            <style jsx>{styles}</style>
        </>
    );
};

export default Container ;

Now, the thing is the {children} of the 1st component is sometimes the 2nd component, and sometimes it's not. Therefore I can't just put the CSS and HTML from the 2ndcomponent into the 1st component - which in turn would fix my problem.

But as you might be able to see, there is an onClick event in the first component. I would like it so that when that is clicked, the state from the click is send to the 2nd component and toggles the className-toggle.

Can this be achieved by doing this, or do I have to set everything up differently ?

And yes, I am quite new to React, so please don't be harsh.

Denver Dang
  • 2,433
  • 3
  • 38
  • 68

2 Answers2

0

Css

I would look into better methods of applying styling with css. Not sure about your project scope/tools but typically all the css files are imported in the dom root and loaded in there. This avoids creating css files for every component.

Here's 9 ways of implementing css for react.

Passing HTML

In react if you want to render component in another component instead of passing it as a child you should import it as follows.

// replace container path with actual path of Container file
// ex './Container.js'

import Container from 'container_path.js'; 

Now Rendering the Component is as simple as including it in the html code.

return (
        <>
            <div className={toggle ? "dark-bg" : "dark-bg active"}>
                <Container/>
            </div>
        </>
    );

Here's a Stack Overflow post of users importing components using react + es6 + webpack. More information on importing components is available there.

State management

In react if you have a state that is being accessed by multiple components the standard is to keep the state in the parent component.

This way you can pass the state as a prop to any children components. You can also create a function which updates this state and pass that function as a prop to the children.

ex:

import React, { useState } from "react"; 
import Container from "./Container.js";
import Navigation from "./Navigation.js"

const Parent = props => {
    const [toggle, toggleState] = useState(false);
   
    return (
        <div>
            <Container toggleState={toggleState} toggle={toggle} />
            <Navigation toggleState={toggleState} toggle={toggle} />
        </div>
    )

}

Before continuing working on your project I would recommend researching functional components vs class components. Here's a helpful article.

Null
  • 119
  • 6
0

Try to wrap second component to function with state from first component as argument.

Wrapper for your second component and using for first component

const putInnerComponent = (stateFromOuterComponent) => <Container toggle={stateFromOuterComponent}/>;

<Navigation children={putInnerComponent}/>

Your first component

import React, { memo, useState } from "react";    
import styles from "./navigation.styles.scss";

const Navigation = ({ children }) => {

    const [toggle, toggleState] = useState(false);

    return (
        <>
            <div onClick={() => toggleState(!toggle)}>
                <p>Test</p>
            </div>
            {children(toggle)}
            <style jsx>{styles}</style>
        </>
    );
};

export default memo(Navigation);

Your second component

import React, { memo, useState } from "react";    
import styles from "./container.styles.scss";

const Container = ({ children, toggle }) => {

    //const [toggle, toggleState] = useState(false);

    return (
        <>
            <div className={toggle ? "dark-bg" : "dark-bg active"}>
                {children}
            </div>
            <style jsx>{styles}</style>
        </>
    );
};

export default Container;
Denhell
  • 526
  • 5
  • 4