Adr*_*n G 2 javascript reactjs react-router-v4
我想知道我必须采用哪种解决方案来解决以下问题:
我不使用任何状态管理库。我“只使用” React。
全局应用程序状态存储在组件中<MyFoodApp/>。它包含一组餐厅对象。
该组件RestaurantPage用于显示餐厅的详细信息,并允许创建新的评论。
在这一点上,我陷入了困境,因为我需要更新 restaurant以的状态存储的特定对象<MyFoodApp />才能添加此提交的评论。
我曾经通过作为道具传递给子组件的函数来更新状态,但是在这种情况下我不能这样做,因为MyFoodApp它不是的父项RestaurantPage。
我是否必须设置Redux以解决此问题,或者有任何解决方法?
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'));
Run Code Online (Sandbox Code Playgroud)
在不实际使用状态管理库的情况下,有两种解决方法可以解决您的问题,
第一:提升状态,
这是最正确的解决方案,因为您的组件和路由不是高度嵌套的,并且数据需要由彼此兄弟的组件处理,
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>
);
}
}
Run Code Online (Sandbox Code Playgroud)
第二:利用上下文API
您可以利用Context何时需要将数据向下传递到不同级别的组件。正如反应文档所说
不要仅仅为了避免将道具向下传递几个级别而使用上下文。坚持需要在多个级别的多个组件中访问相同数据的情况。
您可以使用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>
}
}
Run Code Online (Sandbox Code Playgroud)
然后为消费者创建HOC
import RestaurantContext from 'path/to/restaurantContext'
const withContext = (Component) => {
return (props) => <RestaurantContext.Consumer>
{(restaurant, restaurantUpdater) => <Component {...props} restaurant={restaurant} restaurantUpdater={restaurantUpdater} />}
</RestaurantContext.Consumer>
}
Run Code Online (Sandbox Code Playgroud)
现在您可以在类似
export default withContext(MyFoodApp);
Run Code Online (Sandbox Code Playgroud)
和你的FoodApp可以使用restaurant并restaurantUpdater从像道具
const { restaurant, restaurantUpdater} = this.props
Run Code Online (Sandbox Code Playgroud)
同样,您可以在其他组件中使用它
| 归档时间: |
|
| 查看次数: |
2701 次 |
| 最近记录: |