Каков лучший способ обновить другую переменную состояния, которая зависит от другой переменной состояния при повторном рендеринге? - PullRequest
3 голосов
/ 16 мая 2019

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

На данный момент я являюсьиспользуя componentWillUpdate и вызывая rest и устанавливая все необходимые состояния.

Я пытался использовать метод componentWillUpdate для вычисления и установки других переменных состояния.Но его повторный рендеринг несколько раз.Я предполагаю, что я определенно делаю что-то не так здесь.

export default class Person extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      name: this.props.name,
      age: "",
      country: ""
    };
  }

  componentDidMount() {
    this.setDerivedStates();
  }

  componentWillUpdate() {
    this.setDerivedStates();
  }

  attachListner() {
    document.addEventListner("customEvent", () => {
      this.setState({ name: something });
    });
  }

  setDerivedStates() {
    FetchService.get("url1" + this.state.name).then(response =>
      this.setState({ age: response.age})
    );
    FetchService.get("url2" + this.state.name).then(response =>
      this.setState({ country: response.country })
    );
  }

  render() {
    return (
      <div>
         <p>{this.state.name}</p>
         <p>{this.state.age}</p>
         <p>{this.state.country}</p>
      </div>
    );
  }
}

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

Ответы [ 2 ]

2 голосов
/ 16 мая 2019

Вы можете использовать Promise.all для пакетной обработки двух выборок, поэтому у вас есть только вызов this.setState один раз -

const [resp1, resp2] = await Promise.all([
        FetchService.get("url1" + this.state.name);
        FetchService.get("url2" + this.state.name);
      ]);

this.setState({ age: resp1.age, country: resp2.country });

Кроме того, componentWillUpdate считается небезопасным и будетустарел в будущем.Я бы предложил использовать componentDidUpdate вместо -

componentDidUpdate = (prevProps, prevState) => {
    if (prevState.name !== this.state.name) {
        this.setDerviedStates();
    }
}
2 голосов
/ 16 мая 2019

Вы можете обернуть оба извлечения в Promise.all , который будет ожидать разрешения обоих Promises, в случае сбоя у вас не будет доступа ни к одному Promise/s, который успешно разрешен, и операция будет выданаerror.

Добавить componentDidUpdate , чтобы проверить, изменилось ли состояние имени, если это так, повторно выполнить.

componentDidUpdate(prevProps, prevState) {
  if (prevState.name !== this.state.name) {
    this.setDerivedStates();
  } 
}

async setDerivedStates() {
  const url = `url${this.state.name}`;

  try {
    const [age, country] = await Promise.all([
      FetchService.getAge(url),
      FetchService.getCountry(url),
    ]);

    this.setState({ age, country });
  } catch (e) {
    console.log('something went wrong', e);
  }
}
...