如何在 React Router v4 路由之间共享应用程序状态

2024-01-09

我想知道我需要什么样的解决方案来解决以下问题:

我不使用任何状态管理库。我“只使用”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'));

我发现旧的相关帖子,例如this one https://stackoverflow.com/questions/41108701/react-router-share-state-between-routes-without-redux or this one https://stackoverflow.com/questions/47233605/react-how-can-you-share-the-state-between-views-using-react-router但也许有一种新方法可以解决这个问题。


有几个解决方案可以解决您的问题,而无需实际使用状态管理库,

第一:提升国家地位,

这是最正确的解决方案,因为您的组件和路由不是高度嵌套的,并且数据需要由彼此兄弟的组件处理,

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>
        );
    }
}

第二:使用Context API

您可以利用Context当您的数据需要向下传递到不同级别的组件时。正如反应文档所说

不要仅仅为了避免将 props 向下传递几个级别而使用上下文。戳 需要在多个组件中访问相同数据的情况 在多个层面上。

您可以使用以下方式配置上下文的使用React 16.3 context API https://reactjs.org/docs/context.html#dynamic-context 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>
   }
}

然后为消费者创建一个 HOC

import RestaurantContext from 'path/to/restaurantContext'
const withContext = (Component) => {
    return (props) => <RestaurantContext.Consumer>
        {(restaurant, restaurantUpdater) => <Component {...props} restaurant={restaurant} restaurantUpdater={restaurantUpdater} />}
    </RestaurantContext.Consumer>
}

现在您可以在组件中使用它,例如

export default withContext(MyFoodApp);

你的 FoodApp 可以使用restaurant and restaurantUpdater来自像这样的道具

const { restaurant, restaurantUpdater} = this.props

同样,您可以在其他组件中使用它

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 React Router v4 路由之间共享应用程序状态 的相关文章

随机推荐