使用React Redux路由器,我应该如何访问路由的状态?

Jas*_*n D 8 react-router redux react-router-redux

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

这是我现在在应用程序中所做的大致内容:

<Provider store={Store}>
  <Router history={history}>
    <Route path="/" component={App}>
      <Route path="child/:id" />
    </Route>
  </Router>
</Provider>
Run Code Online (Sandbox Code Playgroud)

应用

const App = (props) => 
  <div className="app">
    <Header />
    <Main {...props}/>
    <Footer />
  </div>
Run Code Online (Sandbox Code Playgroud)

主要

const Main = (props) => 
  <div>
    <MessageList {...props}/>
  </div>
Run Code Online (Sandbox Code Playgroud)

将MessageList

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)
Run Code Online (Sandbox Code Playgroud)

我会喜欢做的,是我所有的组件删除{...}道具,并把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)
Run Code Online (Sandbox Code Playgroud)

不得不在所有内容中传递道具感觉就像是Redux如何清理我的应用程序的一大步.所以如果传递params是正确的,我想知道为什么那更好?

我提出的具体案例如下:

我有一个发送消息的UserInput组件(调度SEND_MESSAGE操作).根据当前页面(聊天室,消息馈送,单个消息等),reducer应将其放在正确的位置.但是,使用react-redux-router,reducer不知道路由,因此无法知道将消息发送到何处.

为了解决这个问题,我需要传递道具,将id附加到我的SEND_MESSAGE操作,现在简单的UserInput处理我的应用程序的业务逻辑.

Dan*_*mov 9

我将解决您的问题(如何根据当前路线调度不同的操作),而不是解决您的问题(如何阅读状态).

制作UserInput一个演示组件.不是在其中调度,而是接受onSend由所有者组件提供的回调的prop.输入将在this.props.onSend(text)不知道任何有关Redux或路由的情况下调用.

然后,制作MessageList一个onSendMessage作为道具接受的演示组件,并转发给它UserInput.再次,MessageList将不知道路线,并将其传递给<UserInput onSend={this.props.onSendMessage} />.

最后,创建一些包装用于不同用例的容器组件MessageList:

ChatRoomMessageList

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

const ChatRoomMessageList = connect(
  mapStateToProps,
  mapDispatchToProps
)(MessageList)
Run Code Online (Sandbox Code Playgroud)

FeedMessageList

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

const FeedMessageList = connect(
  mapStateToProps,
  mapDispatchToProps
)(MessageList)
Run Code Online (Sandbox Code Playgroud)

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


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

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

有一些实验项目保持Redux的整个路由状态,但他们有其他的缺点(例如,路由器做出反应状态是不可序列化的这违背了终极版是如何工作的).所以我认为我上面写的建议应该很好地解决你的用例.