【问题标题】:With React Redux Router, how should I access the state of the route?使用 React Redux Router,我应该如何访问路由的状态?
【发布时间】:2016-06-10 11:53:20
【问题描述】:

使用 react-router-redux,似乎获取路由信息的唯一方法是仅通过 props。是这样吗?

这大致是我现在在我的应用中所做的:

<Provider store={Store}>
  <Router history={history}>
    <Route path="/" component={App}>
      <Route path="child/:id" />
    </Route>
  </Router>
</Provider>

应用程序

const App = (props) => 
  <div className="app">
    <Header />
    <Main {...props}/>
    <Footer />
  </div>

主要

const Main = (props) => 
  <div>
    <MessageList {...props}/>
  </div>

消息列表

let MessageList = (props) => {
  const {id} = props;

  // now I can use the id from the route
 }

const mapStateToProps = (state, props) => {
  return {
    id: props.params.id
  };
};

MessageList = connect(mapStateToProps)(MessageList)

我希望喜欢做的是从我的所有组件中删除 {...props},然后将 MessageList 变成这样:

let MessageList = (props) => {
  const {id} = props;

  // now I can use the id from the route
 }

const mapStateToProps = (state) => {
  return {
    id: state.router.params.id
  };
};

MessageList = connect(mapStateToProps)(MessageList)

对于 Redux 让我的应用程序变得多么干净,必须在所有事情中传递 props 感觉就像是倒退了一大步。所以如果传递参数是正确的,我想知道为什么那更可取?

我提出这个问题的具体案例:

我有一个发送消息的 UserInput 组件(发送 SEND_MESSAGE 操作)。根据当前页面(聊天室、消息提要、单个消息等),reducer 应将其放在正确的位置。但是,使用 react-redux-router,reducer 不知道路由,所以它不知道将消息发送到哪里。

为了解决这个问题,我需要将 props 向下传递,将 id 附加到我的 SEND_MESSAGE 操作中,现在原本简单的 UserInput 正在处理我的应用程序的业务逻辑。

【问题讨论】:

    标签: react-router redux react-router-redux


    【解决方案1】:

    我不会解决您的问题(如何读取状态),而是自己解决您的问题(如何根据当前路线调度不同的操作)。

    将您的 UserInput 设为 presentational component。 let 不是在其中进行调度,而是接受 onSend 属性,它是所有者组件提供的回调。输入将调用this.props.onSend(text),而不知道有关 Redux 或路由的任何信息。

    然后,使MessageList 也成为接受onSendMessage 作为道具的表示组件,并将其转发给UserInput。同样,MessageList 不会知道路由,只会将其传递给&lt;UserInput onSend={this.props.onSendMessage} /&gt;

    最后,为不同的用例创建几个包装MessageList容器组件:

    ChatRoomMessageList

    const mapDispatchToProps = (dispatch) => ({
      onSendMessage(text) {
        dispatch({ type: 'SEND_MESSAGE', where: 'CHAT_ROOM', text })
      }
    })
    
    const ChatRoomMessageList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(MessageList)
    

    FeedMessageList

    const mapDispatchToProps = (dispatch) => ({
      onSendMessage(text) {
        dispatch({ type: 'SEND_MESSAGE', where: 'FEED', text })
      }
    })
    
    const FeedMessageList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(MessageList)
    

    现在您可以直接在路由处理程序中使用这些容器组件。他们将指定正在调度哪个动作,而不会将这些细节泄露给下面的演示组件。让您的路由处理程序负责读取 ID 和其他路由数据,但尽量避免将这些实现细节泄露给下面的组件。在大多数情况下,当它们由道具驱动时会更容易。


    解决原始问题,不,如果您使用react-router-redux,则不应尝试从 Redux 状态读取路由器参数。来自README

    您不应该直接从 Redux 存储中读取位置状态。这是因为 React Router 是异步操作的(用于处理诸如动态加载的组件之类的事情),并且您的组件树可能尚未与您的 Redux 状态同步更新。你应该依赖 React Router 传递的 props,因为它们只有在处理完所有异步代码后才会更新。

    有一些experimental projects确实将整个路由状态保留在 Redux 中,但它们有其他缺点(例如,React Router 状态是不可序列化的,这与 Redux 的工作方式相反)。所以我认为我上面写的建议应该可以很好地解决你的用例。

    【讨论】:

    • 如果我有一些不是由Router 直接创建的嵌套Container Component 怎么办?所以即使我使用withRouter也无法访问路由器参数?如果我不能创建一些嵌套的Container Component,则可以从Router 级别将许多道具发送到我的嵌套组件深处。
    • 您的评论。是的。将容器向下移动到您需要的位置。
    猜你喜欢
    • 2023-03-17
    • 2020-11-05
    • 2018-12-27
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 2016-06-21
    相关资源
    最近更新 更多