Passing data between two sibling React.js components
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...
Related videos on Youtube
IronWaffleMan
Updated on December 10, 2020Comments
-
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 over 8 yearsThanks, 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 over 5 yearsI 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 over 3 years"Hooks & Context API" link reactjs.org/docs/hooks-reference.html6Y8uFbD3XRlZmz9 is broken. Please update. Thanks.