Я использую React и redux, и у меня есть сценарий. У меня есть четыре действия, одно из которых зависит от двух других. Если у нас есть this.props.fetch1(), this.props.fetch2(), this.props.fetch3(), сначала мне нужно получить результат this.props.fetch1() и this.props.fetch2(), а затем использовать поле id каждого результата, чтобы сделать запрос к серверу с помощью redux следующим образом:

1.
  this.props.fetch1()
  this.props.fetch2()

2.
  this.props.fetchResult1.id1
  this.props.fetchResult2.id2

3.
  this.props.fetch3(this.props.fetchResult1.id1, this.props.fetchResult1.id2)

4.
  this.props.fetchResult3

5.
  show the list on the page

А затем, используя this.props.fetchResult3, который является массивом, я составляю список, который будет отображаться на странице во время отрисовки страницы.

Проблема в том, что из-за асинхронности этих действий результат не готов к использованию. Я использовал shouldComponentUpdate для рендеринга до тех пор, пока результат не будет готов, но он останавливает обновление состояний в другой части, и даже если я сравниваю состояния для обновления, он повторно визуализирует компонент, который в моем случае приведет к сбросу значения моих полей на странице с помощью каждое изменение состояния. (у меня есть 2 ввода текста и один флажок на странице для отправки)

shouldComponentUpdate(nextProps, nextState, nextContext) {
        return !isEqual(nextProps.fetchResult1, this.props.fetchResult1) ||
               !isEqual(nextProps.fetchResult2, this.props.fetchResult2) ||
               !isEqual(nextState.fetchResult2, this.state.fetchResult2)

    }


componentDidMount() {
        this.callfetch1fetch2();
    }


componentDidUpdate(prevProps, prevState, snapshot) {
        if (prevProps.fetchResult1 === this.props.fetchResult1 && !this.props.fetchResult2) {
            this.callfetch1fetch2();
        } else {
            this.callfetch3();
        }
}

Я хочу знать, как лучше всего справиться с этим, предотвращая повторную визуализацию, но также правильно обновляя состояние.

Заранее спасибо за любое предложение.

0
Nafis 5 Ноя 2019 в 17:54

2 ответа

Ты можешь использовать:

Promise.all([
  this.props.fetch1(),
  this.props.fetch2()
]).then(response => {
// do something
})

Или создайте одну функцию async / await

async function getResults() {
   let fetchResult1 = await this.props.fetch1(),
   let fetchResult2 = await this.props.fetch1()
}
1
Richard 5 Ноя 2019 в 18:24
Но по-прежнему результат fetch1 недоступен, я вызываю getResults() в componentDidMount
 – 
Nafis
5 Ноя 2019 в 19:09

Используйте обещания для этого сценария.

Ваш компонент будет вызывать только один fetchAll в componentDidMount и componentDidUpdate (вам нужно сделать это в некоторых if в componentDidUpdate - только когда необходимо перезагрузить данные с сервера).

Сопоставьте только fetchResult3 с вашим компонентом, если вам не нужно отображать fetchResult1 и fetchResult2.

function fetchAll() {
    return (dispatch) => {
        return Promise.all([
            dispatch(fetch1()),
            dispatch(fetch2())
        ]).then(([fetchResult1, fetchResult2]) =>
            dispatch(fetchResult3(fetchResult1.id, fetchResult2.id))
        );
    };
}
0
lavor 5 Ноя 2019 в 18:16
Но по-прежнему результат fetch1 недоступен, я вызываю fetchAll() в componentDidMount
 – 
Nafis
5 Ноя 2019 в 19:10
Вы должны обработать случай, когда ваши асинхронные данные недоступны в функции компонента render. Например: если необходимых данных еще нет, верните null. shouldComponentUpdate следует использовать только для повышения производительности. Если вы правильно сопоставили свое состояние с реквизитами, компонент будет повторно отображать каждый раз при изменении сопоставленных данных (то есть после того, как создатель асинхронного действия отправит действие, а редуктор изменит состояние).
 – 
lavor
6 Ноя 2019 в 00:55