Passing data between two sibling React.js components

27,445

Solution 1

I created a jsfiddle with an example of how to share a variable between two components using a parent component.

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {shared_var: "init"};
    }

    updateShared(shared_value) {
        this.setState({shared_var: shared_value});
    }

    render() {
        return (
            <div>
                <CardSearch shared_var={this.state.shared_var} updateShared={this.updateShared} />
                <RunOnServer shared_var={this.state.shared_var} updateShared={this.updateShared} />
                <div> The shared value is {this.state.shared_var} </div>
            </div>
        );
    }
}

class CardSearch extends React.Component {
    updateShared() {
        this.props.updateShared('card');
    }

    render() {
        return (
            <button onClick={this.updateShared} style={this.props.shared_var == 'card' ? {backgroundColor: "green"} : null} >
            card
            </button>
        );
    }
}

class RunOnServer extends React.Component {
    updateShared() {
        this.props.updateShared('run');
    }

    render() {
        return (
            <button onClick={this.updateShared} style={this.props.shared_var == 'run' ? {backgroundColor: "green"} : null}>
            run
            </button>
        );
    }
}


ReactDOM.render(
  <Parent/>,
  document.getElementById('container')
);

Solution 2

As of 2020, Feb; Context API is the way to handle this:

// First you need to create the TodoContext


// Todo.jsx
//...
export default () => {
  return(
    <>
      <TodoContextProvider>
        <TodoList />
        <TodoCalendar />
      </TodoContextProvider>
    </>
  )
}

// Now in your TodoList.jsx and TodoCalendar.jsx; you can access the TodoContext with:
//...
const todoContext = React.useContext(TodoContext);
console.log(todoContext)
//...
//...

Check this video tutorial by The Net Ninja for Hooks & Context API

Good Luck...

Share:
27,445

Related videos on Youtube

IronWaffleMan
Author by

IronWaffleMan

Updated on December 10, 2020

Comments

  • IronWaffleMan
    IronWaffleMan over 3 years

    I have two instances of a component (a search field) on a page, with a second component (a button that makes server calls) between them, as such:

    ReactDOM.render(
        <table>
        <tbody>
            <tr>
                <td><CardSearch items={ cards } placeholder="Card 1 here" /></td>
                <td><RunOnServer url="py/comparecards" /></td>
                <td><CardSearch items={ cards } placeholder="Card 2 here"/></td>
            </tr>
        </tbody>
        </table>,
        document.getElementById('root')
    );

    All I want to do is pass one parameter each, unmodified, from the CardSearch fields to the RunOnServer button, but I'll be damned if it's easy. According to this I can use this.state.var as a prop, but doing that gave me 'undefined.state.var' when the code compiled instead. React's official docs are not great; they simply tell me to go Flux myself, which seems daft... I shouldn't need a whole new architecture to pass a simple variable from one component to another.

    I also tried making local vars in the file that's doing the rendering, but they get passed to the components as props and you can't modify props in a component.

  • IronWaffleMan
    IronWaffleMan over 8 years
    Thanks, that worked out. I created two updateShared functions, one for each CardSearch component I have, and they update var1 or var2 respectively. One trick was, I was calling this.props.updateShared(this.state.var) right after this.setState({string: var}), but the var being passed in was the old one, not the updated one I was setting the state with. So I passed this.props.updateShared(var) as the callback to this.setState. Not sure why it wasn't updating the state value after the setState call though...
  • temporary_user_name
    temporary_user_name over 5 years
    I would love to see this answer rewritten with ES6 classes instead of React.createClass. It's just mildly distracting. Well, I suppose I could do it myself.
  • Kamlesh
    Kamlesh over 3 years
    "Hooks & Context API" link reactjs.org/docs/hooks-reference.html6Y8uFbD3XRlZmz9 is broken. Please update. Thanks.

Related