在特定调度后从组件级别重定向 - redux thunk

Posted

技术标签:

【中文标题】在特定调度后从组件级别重定向 - redux thunk【英文标题】:redirect from component level after specific dispatch - redux thunk 【发布时间】:2017-01-28 07:32:29 【问题描述】:

我有一个相当简单的用例,但很难找到合适的答案。我正在使用 React、Redux、React Router 和 redux thunk 中间件。

可以说,我有两个模块食物标签和食物。这些模块具有单独的创建、列表、编辑页面/组件。在实际用例中,食物标签没有特殊价值。每当创建食物对象时,都会将单独的标签插入到食物对象的 tags 属性中。

一般用例是,成功创建任何项目后,react router 将其重定向到列表页面。

每当我从 food-tag 模块中调用 createTag 操作时,我都可以用一种老套的方式来完成它。就像在成功发送之后,我可以调用

browserHistory.push('/dashboard/tags')

这让我遇到了一个问题,我可以从食物创建组件内联创建食物标签。代码如下

actions.js

export function createTag(tag) 
return function (dispatch) 
    axios.post(API_URL + 'api/tags', tag)
        .then((response) =>  
            // I CAN DO REDIRECT HERE,BUT THIS CAUSES THE PROBLEM
            dispatch(type: 'TAG_CREATE_RESOLVED', payload:response);
            toastr.success('Tag created Successfully.......!');
        )
        .catch((err) => 
            dispatch(type: 'TAG_CREATE_REJECTED', payload: err);
            toastr.warning(err.message);
        )
    

component/container.js

createTag () 
  //validatation & others....
  this.props.createTag(tag)

react-redux 连接

function mapDispatchToProps (dispatch) 
    return bindActionCreators(
        createTag: createTag
    , dispatch)

food/create.js 中的模式几乎相同

$('#food-tags').select2(select2settings).on('select2:selecting', function (event) 
        let isNewTagCreated = event.params.args.data.newOption,
            name = event.params.args.data.text;
        if (isNewTagCreated && name !== '') 
            reactDOM.props.createTag(name); // reactDOM = this context here
        
    );

基本上我想要的是,我想在组件级别访问正在调度的动作类型,以便我可以从组件重定向并显示通知,而不是动作重击。可能是我没有以正确的方式思考。可能有一个非常简单的解决方法。

【问题讨论】:

据我了解,您想将toastr.success 调用移动到组件代码中,但您不知道如何,对吧? 是的。还有重定向代码browserHistory.push 【参考方案1】:

很高兴知道redux-thunk 从函数中传递了返回值。所以你可以从动作创建者那里返回承诺并等待它在你的组件代码中完成

export function createTag(tag) 
  return function (dispatch) 
    return axios.post(API_URL + 'api/tags', tag) // return value is important here
      .then((response) => dispatch(type: 'TAG_CREATE_RESOLVED', payload:response))
      .catch((err) => 
        dispatch(type: 'TAG_CREATE_REJECTED', payload: err)
        throw err; // you need to throw again to make it possible add more error handlers in component
      )
  

然后在你的组件代码中

createTag () 
  this.props.createTag(tag)
    .then(() => 
      toastr.success('Tag created Successfully.......!');
      this.props.router.push() // I assume that you have wrapped into `withRouter`
    )
    .catch(err => 
       toastr.warning(err.message);
    );


现在您已经在操作逻辑和用户界面之间进行了适当的分离。

【讨论】:

感谢您的回答。基本上我自己也提出了类似的解决方案。相反,我通过了回调。这是要点github.com/gaearon/redux-thunk/issues/96

以上是关于在特定调度后从组件级别重定向 - redux thunk的主要内容,如果未能解决你的问题,请参考以下文章

如何在 redux saga 中调度操作之前将数据设置为 localStorage

React Redux:调度时的无限循环

React Page 在根据 redux 值重定向之前闪烁

尝试设置 redux 历史记录,以便我可以重定向

使用 redux-saga 重定向反应路由器

使用 react-router-dom v4 在 redux 操作中重定向