【问题标题】:Triggering action on route change with react-router使用 react-router 触发路由更改操作
【发布时间】:2016-02-10 16:23:58
【问题描述】:

我正在使用 react、redux 和 react-router 创建一个小型应用程序。

我有一个包含在<Link /> 中的项目列表,当我单击其中一个时,我希望该项目在触发链接操作之前的状态下设置为currentItem。有一个动作可以做到这一点 - selectItem(item) - 但我不知道如何触发它。

我应该在componentWillUnmount 上触发它吗?在那种情况下 - 我如何确定点击了什么项目?我应该创建一个调度操作的<Link onClick={}/> 处理程序吗?

然后项目页面将检查是否设置了 currentItem,如果没有设置,则可能从后端获取它。

【问题讨论】:

    标签: reactjs react-router redux


    【解决方案1】:

    我发现使用 Link 效果很好。

    您可以使用它来访问事件和原始组件的值。像这样:

    <Link to={address} onClick={actions.handlerFunction}>

    其中 handlerFunction 是一个 redux 动作创建者。然后在您的 handlerFunciton 中,您可以像这样访问事件和元素的值:event.target.value。 您的动作创建者应如下所示:

    export function handlerFunction(event) {
        return {
            type: 'CHANGE_SOMETHING',
            prop: event.target.value
        }       
    }
    

    然后你可以在你的reducer中设置状态。

    如果您不需要该事件,但想将一些数据传递给动作创建者,您可以像这样使用它:

    <Link to={address} onClick={() => actions.handlerFunction(someData)}>

    to 属性添加到链接很重要,它将更新您在地址栏中看到的地址。

    See more in the Link docs on github.

    【讨论】:

      【解决方案2】:

      您也可以在“根”组件中使用componentWillReceiveProps 执行此操作,并将nextPropsthis.props 进行比较。 路由器将 props 传递给组件(locationhistory 等),您可以处理这些。

      例如:

      ReactDOM.render(
          <Router>
              <Route path="/" component={App}/>
          </Router>,
          document.getElementById('root')
      );
      

      在您的 App 组件中:

      componentWillReceiveProps(nextProps) {
      if (nextProps.location.pathname != this.props.location.pathname) {
      // do stuff
      }
      

      附:我仍然是一个反应菜鸟,所以如果您对此方法有任何意见或建议,请发表评论。

      【讨论】:

        【解决方案3】:

        使用上次 React 更新中的新 useEffectuseRef 助手,您可以这样做:

        import React, { useEffect, useRef } from 'react';
        import { withRouter, RouteComponentProps } from 'react-router';
        
        function Bob({ location: { key } }: RouteComponentProps) {
          const oldURL = useRef(key); // key is a unique identifier set by react-router
        
          useEffect(() => {
            if (oldURL.current !== key) {
              // trigger your action here
            }
            oldURL.current = key; // refresh the oldURL after every render
          });
        }
        
        export default withRouter(Bob);
        
        

        需要useRef 才能将旧值保留在内存中。

        然后,您将旧的location.key 与新的进行比较。

        如果比较location.pathname,则不会检测到搜索参数的变化,因为路径名只取域名和搜索参数之间的文本:

        htpp://foo.bar/products?filterBy=price
               ^           ^         ^
         domain name | pathname | search params
        

        通过比较location.key,即使filterBy发生变化,您的操作也会被触发。
        不是location.pathname

        【讨论】:

          猜你喜欢
          • 2017-10-30
          • 1970-01-01
          • 2018-01-02
          • 1970-01-01
          • 2015-09-24
          • 2016-09-21
          • 2016-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多