I would like to know what kind of solutions I have to solve the following issue:
I don't use any state mangement library. I "only use" React.
The global application state is stored in the component <MyFoodApp/>
. It contains an array of restaurant objects.
The component RestaurantPage
is used to display the details of a restaurant and allows to create a new review.
At this point I'm stuck because I need to update a specific restaurant
object stored in the state of <MyFoodApp />
in order to add this submitted review.
I used to update the state via functions passed as props to the children components but in this case I can't because MyFoodApp
is not a parent of RestaurantPage
.
Do I have to set up Redux
to fix this issue or is there any workarounds ?
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Link, Route, Switch } from 'react-router-dom';
import EasyFoodApp from './js/components/EasyFoodApp';
import RestaurantPage from './js/components/RestaurantPage';
import NotFound from './js/components/NotFound';
class Root extends React.Component {
render() {
return (
<Router>
<div className="router">
<Switch>
<Route exact path="/" component={MyFoodApp} />
<Route
path="/restaurant/:slug"
component={RestaurantPage}
/>
<Route render={() => <NotFound />} />
</Switch>
</div>
</Router>
);
}
}
ReactDOM.render(<Root />, document.getElementById('root'));
I found old related posts like this one or this one but there is maybe a new way to handle this issue.
There are a couple of solution to your problem without actually using a state management library,
First: Lift the state up,
This is the most correct solution since your components and routes are not highly nested and the data needs to handled by the components which are siblings of each other,
class Root extends React.Component {
state = {
restaurant: [] // store the restaurant data here instead of MyFoodApp
}
restaurantUpdater = () => {
//utility function to update state
}
render() {
return (
<Router>
<div className="router">
<Switch>
<Route exact path="/" render={props => <MyFoodApp {...props} restaurant={this.state.data} restaurantUpdater={this.restaurantUpdater} />} />
<Route
path="/restaurant/:slug"
render={props => <RestaurantPage {...props} restaurant={this.state.data} restaurantUpdater={this.restaurantUpdater} />}
/>
<Route render={(props) => <NotFound {...props}/>} />
</Switch>
</div>
</Router>
);
}
}
Second: Make use of Context API
You can make use of Context
when your data needs to be passed down to components at different levels. As the react docs say
Don’t use context just to avoid passing props a few levels down. Stick to cases where the same data needs to be accessed in many components at multiple levels.
You can configure the use of context using React 16.3 context API
like
export const RestaurantContext = React.createContext({
restaurant: [],
restaurantUpdater: () => {},
});
class RestaurantProvider extends React.Component {
state = {
restaurant: [] // store the restaurant data here instead of MyFoodApp
}
restaurantUpdater = () => {
//utility function to update state
}
render() {
<RestaurantContext.Provider value={this.state}>
{this.props.children}
</RestaurantContext.Provider>
}
}
and then create an HOC for the consumer
import RestaurantContext from 'path/to/restaurantContext'
const withContext = (Component) => {
return (props) => <RestaurantContext.Consumer>
{(restaurant, restaurantUpdater) => <Component {...props} restaurant={restaurant} restaurantUpdater={restaurantUpdater} />}
</RestaurantContext.Consumer>
}
Now you can use it in the component like
export default withContext(MyFoodApp);
and your FoodApp can use restaurant
and restaurantUpdater
from props like
const { restaurant, restaurantUpdater} = this.props
similarly you can use it in the other components
You could manage data without redux if either of the scenarios matched your arrangement of components:
But neither of the relationships satisfies your arrangement of the components since the two components are new root components.
When the components can't communicate between any sort of parent-child relationship, the documentation recommends setting up a global event system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With