The general solution is to make a parent somewhere up the tree that delegates the data and actions to its children. Since React models itself as a "tree", it means that at some point these components will share a parent. Let's just say it's called <AppContainer>
.
<AppContainer> <-- this will delegate the data to the components below it
<Header>
<Navigation />
</Header>
<Content Grid>
<ApiResult />
</Content Grid>
</AppContainer>
You then hoist the functions up to the <AppContainer>
, which delegates the data to the components below it. Suppose clicking the menu shows "saved" items. You might model behavior like this:
class AppContainer extends Component {
state = { showSaved: true };
onMenuClick = () => {
this.setState({ showSaved: true }); // example
};
render() {
return (
<div>
<Header>
<Navigation
showSaved={this.state.showSaved}
onMenuClick={this.onMenuClick}
/>
</Header>
<ContentGrid>
<ApiResult menuClicked={this.state.showSaved} />
</ContentGrid>
</div>
);
}
}
This will allow you to access that variable in both <ApiResult>
and <Navigation>
. When that variable is changed in the state, it will trigger re-renders to both, ensuring they are up to date.