React Router + Redux - 在路由更改时调度异步操作?

IT技术 javascript reactjs react-router redux
2021-04-27 13:09:47

我有一个使用 redux 和 react-router 的通用 React 应用程序。

我有几条路线如下:

/2016
/2015
/2014
/2013

等等。

每个路由都需要来自 API 的数据。目前,我让<Link>Navigation 组件中元素分派了一个异步操作onClick,该操作使用来自该路由的 API 的数据填充商店。

对于 MVP,我只是post: {}在路由更改时用新的帖子内容覆盖商店中的内容,这样我们就可以获得 API 上的任何新内容。

我已经意识到在<Link>按钮上设置动作调度器并不是最佳选择,因为点击后退按钮不会重新触发动作调度以获取前一路线的内容。

有没有办法让 React Router 在路由发生变化时触发调度操作?(限制它听一组特定的路线将是一个奖励)。

我意识到我应该从商店获取历史记录,但是现在,通过触发操作调度以获取新内容再次点击 API 更容易

干杯。

3个回答

在“生命周期”钩onEnteronChange在已被删除阵营路由器4,这使得大多数其他的答案对这个问题过时出。

虽然我建议您使用组件生命周期方法来实现您的目标,但这里是您的问题的答案,它适用于 React-router 4。

今天的工作是使用由 React 路由器开发人员自己创建的History 库来监听历史变化,并从那里分派异步操作。

// history.js
import createHistory from "history/createBrowserHistory"

const history = createHistory()

// Get the current location.
const location = history.location

// Listen for changes to the current location.
const unlisten = history.listen((location, action) => {
    //Do your logic here and dispatch if needed
})

export default history

然后在您的应用程序中导入历史记录

// App.js
import { Router, Route } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import history from './history';

class App extends Component {
  render() {
    return (
      <Router history={history}>
        <div>
          <Route exact path="/" component={Home} />
          <Route path="/login" component={Login} />
        </div>
      </Router>
    )
  }
}

来源:历史库 React 路由器文档

是的 React Router 有 onEnter 和 onLeave 钩子。您可以构建路由来获取您的store实例,以便您可以在这些帮助程序中访问它:

const createRoutes = (store) => {
  const fetchPosts = () => store.dispatch({
    types: ['FETCH_POSTS', 'FETCH_POSTS_SUCCESS', 'FETCH_POSTS_FAIL',
    url: '/posts'
  });

  return (
    <Route path="/" component={App}>
      <Route path="posts" component={PostList} onEnter={fetchPosts}/>
      <Route path="posts/:id" component={PostDetail} />
    </Route>
  )
}

更好的解决方案是使用类似redial或的东西redux-async-connect这允许您将组件的数据依赖项与组件放在一起,同时保留在不接触网络的情况下测试组件的能力。

编辑:这适用于不再受支持的旧版本react-router.

我更喜欢从渲染props本身调度动作:

<Route to="path" render={ props => {
  this.props.toggleInfoLayer(true);
  return <UserInfo />;
}} />

这是假设您正在使用 Redux 的mapDispatchToProps论点。

我尝试使用已接受的答案中提到的历史更改事件处理程序,但我发现从流氓文件中分派操作是不可取的。我不得不考虑的另一个地方,当时 Redux 已经提供了太多太多。