何处以及如何以异步方式请求数据作为道具传递给React Router(v 1)

时间:2016-01-06 10:24:27

标签: reactjs react-router

在阅读了很多关于这个主题的问题之后,我仍然不确定异步获取数据的最佳方法是哪种方法,以后将这些数据作为道具传递给React Router v1.0.0及以上的子路由。

我的路线配置看起来像这样:

import { render } from 'react-dom';
// more imports ...

...

render(
  <Router>
  <Route path="/" component={App} />
    <IndexRoute component={Dashboard}/>
    <Route path="userpanel" component={UserPanel}/>
  </Router>,
  document.getElementById('container')
)

在我的App组件中,我有代码,如果提取成功,它会异步地从后端获取数据并将其合并到其状态中。我在componentDidMount内使用App

App的状态看起来像这个人为的例子:

{
  user: {
    name: 'Mike Smith',
    email: 'mike@smith.com'
  }
}

我希望将状态的user部分作为道具传递到我的IndexRouteuserpanel路线。但是我不确定应该怎么做。

想到几个问题:

  1. 我应该在代码中的其他位置放置异步数据请求吗?
  2. 我应该使用React Router api(如onEnter)而不是React生命周期方法来获取数据吗?
  3. 如何将App的状态(用户)作为道具传递给DashboardUserPanel组件?
  4. 我不确定如何使用React.cloneElement执行此操作,如其他答案所示。
  5. 感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

当您的应用程序启动时,您可以执行一项操作,您将调用API并获取数据并注册您的Route 我的index.js是条目文件,然后

这里我使用React-Router 0.13.3您可以根据新路由器

更改语法
fetchData(config.url+'/Tasks.json?TenantId='+config.TenantId).then(function(items)
{
    var TaskData=JSON.parse(JSON.stringify(items.json.Tasks));
    var Data=[];
    Object.keys(TaskData).map(function(task){
        if(TaskData[task].PageName !=='' && TaskData[task].PageUrl !=='')
        {
            Data.push({PageName:TaskData[task].PageName,path:TaskData[task].PageName+'/?:RelationId',PageUrl:TaskData[task].PageUrl});
        }
    });

    Data.push({PageName:'ContainerPage',path:'/ContainerPage/?:RelationId',PageUrl:'./pages/ContainerPage'});

    var routes=require('./routes')(Data);
    $("#root").empty();
    Router.run(routes,function(Handler){
        React.render(<Handler />,document.getElementById('root'));
    });

    React.render(<UserRoles />, document.getElementById("userrole"));
}).catch(function(response)
{
    showError(response);
});

我已将数据传递到routes.js文件,如var routes=require('./routes')(Data);,我的routes.js文件看起来像

export default (data =>
  <Route name="App" path="/" handler={App}>
    <NotFoundRoute handler={require('./pages/PageNotFound')} />
    <Route handler={TaskList} data={data} >
    </Route>
{ data.map(task =>
  <Route name={task.PageName} path={task.path}  handler={require(task.PageUrl)}>
  </Route>
    ) }
</Route>
);

答案 1 :(得分:0)

您要求的是路线之间的持续数据,而不是路由器的工作。

你应该创建一个商店(用通量表示),或模型/集合(用MVC术语) - 反应的常用方法是类似于通量的。我推荐redux

在redux文档中,它有example获取reddit用户:

componentDidMount() {
  const { dispatch, selectedReddit } = this.props
  dispatch(fetchPostsIfNeeded(selectedReddit))
}

我个人认为flux / redux不是实现最简单的方法,但它可以很好地扩展。即使您决定使用其他内容,基本概念也是如此:

  • 你是正确的,因为Facebook suggests,异步提取在componentDidMount中最佳。
  

如果要与其他JavaScript框架集成,使用setTimeout或setInterval设置计时器,或发送AJAX请求,请在此方法中执行这些操作。

  • 接下来,您需要在可以从其他组件访问的商店/模型中设置此数据。

关于redux(使用react-redux)的好处是,对于每个组件,您可以说“这是此组件感兴趣的操作”,然后该组件可以简单地调用UserActions.fetchUserIfNeeded()之类的操作并且操作将确定它是否已经拥有该用户或是否应该被提取,之后它将重新呈现并且支柱将可用。

回答问题4:你想克隆什么?为什么?如果是孩子,请参阅this answer

答案 2 :(得分:0)

我不完全确定我理解这个问题,但我最近也将属性传给了我的路线的孩子们。请原谅我,如果这不是最好的方式,但你必须克隆你的孩子并编辑它们,然后传递副本而不是孩子。我不确定为什么会做出反应,反应路由器让你这样做,但试试这个:
let children (or whatever you want to name it) = React.Children.map(this.props.children, (child) => { return React.cloneElement(child, {name of property: property value}); }); 之后,您应该能够在子路径中的this.props中访问这些属性。请问你是否有任何问题,因为这很令人困惑。