Как получить состояние Redux до повторного рендеринга компонента? - PullRequest
0 голосов
/ 08 ноября 2019

Из-за того, как данные передаются через приложения 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 ]

1 голос
/ 08 ноября 2019

Хорошо, если я правильно понимаю ваш вопрос, ваш метод func addItemA, тогда addItemB зависит от ответа от addItemA, addItemA будет асинхронной операцией, поэтому в вашем действии addItemA, когда вы добавляете элемент, вы можете просто вернуть обещание из вашего действия. который при разрешении возвращает идентификатор вновь созданного элемента, и внутри вашего компонента вы можете обработать его в блоке 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...
  }

Надеюсь, это поможет

0 голосов
/ 11 ноября 2019

Делай на лот туда-сюда, и, тестируя, я столкнулся со многими стенами, пытаясь выяснить это, но в конце концов понял. Вот что вам нужно сделать.

Примечание. Это не считается частью общедоступного API React Redux и может выйти из строя без уведомления. Мы признаем, что у сообщества есть случаи использования, где это необходимо, и постараемся сделать так, чтобы пользователи могли создавать дополнительные функции поверх React Redux, но наше конкретное использование контекста считается деталью реализации. Если у вас есть дополнительные варианты использования, которые недостаточно охвачены текущими API, пожалуйста, подайте проблему, чтобы обсудить возможные улучшения API. - https://react -redux.js.org / using-реагировать-редуцировать / обращаться к магазину # using-реагировать-reduxcontext-напрямую

Убедитесь, что реагирует Пакет 16.8.3 или позже. Убедитесь, что ваш пакет реаги-редукс 7.1 или выше. Вам нужны эти версии из-за нового способа (в React 16.8.3) React передает Context дочерним компонентам. Мы заботимся о контексте, потому что этот новый API React Context работает так, как работает ReactReduxContext .

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 без , полагаясь на сам компонент, который будет обновляться / перерисовываться, - это использовать метод, который я описал выше.

0 голосов
/ 08 ноября 2019

shouldComponentUpdate должно помочь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...