在重新渲染组件之前如何获得Redux状态?

时间:2019-11-08 03:08:30

标签: reactjs redux react-redux

由于how data flows通过React-Redux应用程序,在商店中更新的数据在React组件中不可用,直到该组件重新渲染为止。

我的要求是,在给定的组件中,我想使用更新的存储,而无需重新渲染该组件。我想做这样的事情:

import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect } from "react-redux";

import * as AActions from "../aactions";
import * as BActions from "../bactions";
import * as CActions from "../cactions";
class MyComponent extends Component<Props>{

    constructor(props){
        super(props);
        this.func = this.func.bind(this);
    };

    func(){
        // Add item to A
        this.props.addAItem("value");

        // Get id of newly added item in A
        let addedA = this.props.A.find(a => a.name === "value");

        // Insert new items in B with the id of A
        this.props.addBItem(addedA.id, "valueB");

        // etc...
    }

    render(){
        <div onClick={() => this.func()}>click me</div>
    }
}

function mapStateToProps(state, props){
    return {
        A: state.A,
        B: state.B,
        C: state.C
    };
}
function mapDispatchToProps(dispatch){
    return bindActionCreators({...AActions, ...BActions, ...CActions}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

此操作不起作用,因为props直到MyComponent重新渲染后才会更新。我无法调用this.props.A.find(a => a.name === "value");,因为道具不会具有最新添加的“ A”值。就我而言,我等不及要重新渲染MyComponent。在MyComponent中访问最近状态有什么选择?

我已经做过这样的事情,但这绝对是可怕的,但是确实有效...

func(){
    if (this.props.step1){
        // Add item to A
        this.props.addAItem("value");

        this.props.setStep2();
    } else if (this.props.step2) {
        // Get id of newly added item in A
        let addedA = this.props.A.find(a => a.name === "value");

        this.props.setStep3();
    }
    // etc...
}

3 个答案:

答案 0 :(得分:1)

好吧,如果我对问题的理解正确,那么您的func方法addItemA然后addItemB依赖于addItemA的响应,addItemA是异步操作,因此在addItemA操作中,添加项目时,您可以简单地从操作中返回promise解析时返回新创建元素的ID,在组件内部,您可以在

中处理then块
func(){
    // Add item to A
    this.props.addAItem("value").then((id) => {
    // no need to find the id now
    // Insert new items in B with the id of A
    this.props.addBItem(id, "valueB");

    });


     // etc...
  }

希望有帮助

答案 1 :(得分:0)

反复来回 并进行测试,我碰到了很多墙,试图弄清楚这个,但最终弄清楚了。这就是您需要做的。

  

注意:这不被视为React Redux公共API的一部分,并且可能会在没有通知的情况下中断。我们确实认识到社区有一些必要的用例,并且会尝试使用户有可能在React Redux之上构建附加功能,但是我们对上下文的特定使用被视为实现细节。如果您还有其他用例,但当前的API尚未充分涵盖这些用例,请提出问题以讨论可能的API改进。 -https://react-redux.js.org/using-react-redux/accessing-store#using-reactreduxcontext-directly

确保您的反应软件包为16.8.3或更高版本。确保您的 react-redux 软件包为7.1或更高。由于新方法(在React 16.8.3中),您需要这些版本。React将Context传递给子组件。我们关心Context,因为 ReactReduxContext 是这种新的React Context API的工作方式。

ReactReduxContext是我们获取组件中商店当前状态所需要的魔力。请注意我们下面组件中的更改

import React, { Component } from "react";
import { bindActionCreators } from "redux";
import { connect, ReactReduxContext } from "react-redux"; // CHANGED!

import * as AActions from "../aactions";
import * as BActions from "../bactions";
import * as CActions from "../cactions";
class MyComponent extends Component<Props>{

    constructor(props){
        super(props);
        this.func = this.func.bind(this);
    };

    func(store){ // CHANGED!
        // Add item to A
        this.props.addAItem("value");

        // Get id of newly added item in A
        let addedA = store.getState().A.find(a => a.name === "value"); // CHANGED!

        // Insert new items in B with the id of A
        this.props.addBItem(addedA.id, "valueB");

        // etc...
    }

    // CHANGED!
    render(){
        <ReactReduxContext.Consumer>
            {({store}) => {
                return <div onClick={() => this.func(store)}>click me</div>
            }}
        </ReactReduxContext.Consumer>
    }
}

function mapStateToProps(state, props){
    return {
        A: state.A,
        B: state.B,
        C: state.C
    };
}
function mapDispatchToProps(dispatch){
    return bindActionCreators({...AActions, ...BActions, ...CActions}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

魔术是store.getState(),它将返回更新的Redux存储。

我想指出的是,我对redux-thunk进行了广泛的研究,但是这种方法并没有最终满足我的需求。主要问题是在组件中使用 bindActionCreators 。因为我正在使用 bindActionCreators ,所以我调用的任何操作都期望有一个空对象,该对象将被分派到Redux存储。

我尝试了多种方法尝试在操作中返回更新的Redux状态,但是由于我使用的是bindActionCreators,因此无法从给定操作返回Redux状态的值。不依赖要更新/重新呈现的组件本身而检索更新的Redux存储状态 的唯一方法是使用我上面概述的方法。

答案 2 :(得分:-1)

shouldComponentUpdate应该可以解决问题