【问题标题】:How to force an update from inside mapStateToProps?如何从 mapStateToProps 内部强制更新?
【发布时间】:2017-06-12 09:19:56
【问题描述】:

我说的是connectmapStateToProps 参数。

我的一个组件有一个名为rules 的属性,它是一个函数数组。在mapStateToProps 中,我调用这些规则,传入当前状态。如果没有错误,规则会返回错误消息或 true。我将这些错误消息放入一个新的 prop 中,以便最终组件接收错误消息数组而不是函数数组。

到目前为止,这一直很好,但现在我想添加对异步规则的支持。我现在的计划是,每当规则返回 Promise 而不是错误字符串时,我会将“Checking...”之类的消息推送到错误消息数组中,但是一旦完成 Promise,我需要“刷新”这个数组并插入解析的消息。

我想如果我可以force an update,那么redux 将不得不再次调用mapStateToProps。在这种情况下,所有规则都将被重新评估,但如果我不小心,我会收到一个新的 Promise,它会立即恢复原状。 但是,如果我记住这些规则,那么我可以取回与以前相同的 Promise 实例,然后 check if it's settled 然后将该值放入我的错误数组中。

所以现在唯一的问题是弄清楚如何在 mapStateToProps 的上下文中获取对组件实例的引用,它只能访问当前状态和道具。

我的 Promise 解决后,有什么方法可以强制重新渲染?

或者,如果我可以dispatch 解决某个操作,我也可以使用它。

【问题讨论】:

  • 认为这对connectAdvanced是可行的。有了它,我可以同时访问 state、props 和 dispatch 函数,这应该给我足够的权力来在 promise 解决时触发刷新。

标签: reactjs redux react-redux


【解决方案1】:

创建一个有状态的组件怎么样?如果您将 Promise 的结果保留在组件的状态中,一旦 Promise 解决,它将自动重新渲染组件。

import React, {Component} from 'react';
import {connect} from 'react-redux;
import Promise from 'promise';

class MyStatefulComponent extends Component {
    constructor(props) {
        this.state = {
            messages: [] // initialize empty, or with the synchronous rules
        };
    }

    componentWillMount() {
        const setState = this.setState;
        const rules = this.props.rules; // rules contains a list of either evaluated rules or promises
        Promise.all(rules).then(results => {
            // this is executed once all the promises in rules have resolved
            // setState will trigger a re-render of this component
            setState({
                messages: [] // construct your array of messages here from the results
            });
        })
    }

    render() {
        // render your list of messages
        return <ul>
            {this.state.messages.map(message => <li>{message}</li>)}
        </ul>;
    }
}

export default connect(
    (state, ownProps) => ({
        rules: ownProps.rules.map(rule => rule(state))
    })
)(MyStatefulComponent);

【讨论】:

  • 我没有考虑过!不过,我必须将所有这些状态都纳入 HOC;我正在为输入构建一个包装器,并且重复的样板太多。此外,我将无法再包装无状态功能组件。但是...如果我的计划不成功,我会试一试,谢谢你的想法!
【解决方案2】:

你不能在mapState 中这样做。 mapState 函数旨在完全同步。如果您需要异步执行某些操作,请在 mapState 之外触发,将一些值存储在 state 中,并使用结果更新它们以强制 mapState 重新运行。

【讨论】:

  • 我不确定在mapStateToProps 之外我将如何做到这一点。我需要组件的 state 和 props 来评估这些规则。我可以在我的减速器中获得状态,但是我错过了道具。即使我发送了所有道具以及我发送的每个动作,它也无济于事,因为那时我只能重新验证触发动作的字段,但我有可能会根据其他字段的值更改有效性的条件字段。
  • 您需要某种中间件来完成您的要求。 Redux-saga github.com/redux-saga/redux-saga 或 Redux Thunk github.com/gaearon/redux-thunk 很受欢迎
  • @AnilRedshift 我认为这些库中的任何一个都无法解决我描述的问题。我无法在需要的地方访问dispatch,因此处理分派操作的中间件无济于事。
猜你喜欢
  • 2016-03-12
  • 1970-01-01
  • 2019-03-10
  • 2020-09-07
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 2022-11-11
相关资源
最近更新 更多