user1255102
user1255102

Reputation: 486

How to pass state from parent to child in react?

How do I pass a state attribute from parent to child? In the following implementation, the Dropdown component has a state "isActive" and I want to access it in the Button component to attach propper styling to it. The Dropdown has to generic as it is supposed to take different sorts of buttons.

<Dropdown items="...">
  <Button active ="false" />
</Dropdown>

Dropdwon.js

...

    constructor(props){
        super(props)
        this.state = {
         isActive: true,
        }
    }

    render (){
        return (
               <div className={styles.toggle} onClick={(event) => this.showMenu(event)}>
                    {this.props.children} /* want to set active prop for the child button here */
                </div>
        );
} 

...

Upvotes: 0

Views: 106

Answers (3)

Jolly
Jolly

Reputation: 1768

You have two possibilities:

  1. Lift your Dropdown state and keep it in its parent component;
  2. Use useContext hook;

The first approach would be better, but it may not be good for your application (I cannot know that). Let me make an example for both cases.


This is an example where I've lifted the isActive state to the parent component.

const ParentComponent = () => {
    const [isActive, setIsActive] = useState(false);

    handleIsActiveChange = (newValue) => {
        setIsActive(newValue);
    }

    <Dropdown isActive={isActive} setIsActive={handleIsActiveChange}>
        <Button isActive={isActive} />
    </Dropdown>
}

const Dropdown = props => {
    // You can use `props.isActive` to know whether the dropdown is active or not.
    // You can use `props.handleIsActiveChange` to update the `isActive` state.
}

const Button = props => {
    // You can use `props.isActive` to know whether the dropdown is active or not.
}

Instead, this exploits the useContext API:

const dropdownContext = React.createContext(null);

const Dropdown = props => {
    const [isActive, setIsActive] = useState(false);

    return (
        <dropdownContext.Provider value={{ isActive }}>
            {props.children}
        </dropdownContext.Provider>
    );
}

const Button = props => {   
    const dropdownCtx = React.useContext(dropdownContext);

    // You can use `dropdownCtx.isActive` to know whether the dropdown is active or not.
}

Upvotes: 1

Treycos
Treycos

Reputation: 7492

Aside from the answer I linked, there might be another way of achieving this that I didn't see mentioned.

You can send a function as a children element of your dropdown which will take isActive as a variable :

<Dropdown items="...">
  {isActive => <Button active={isActive} />}
</Dropdown>

Then, is the render function, simply call the function and send your state value as a parameter :

render(){
    return (
        <div className={styles.toggle} onClick={(event) => this.showMenu(event)}>
            {this.props.children(this.state.isActive)}
        </div>
    );
} 

Upvotes: 1

Burak Gavas
Burak Gavas

Reputation: 1354

<Dropdown >
  <Button isActive={this.state.isActive} />
</Dropdown>

In your button get it with this.props.isActive

Upvotes: 0

Related Questions