функция обратного вызова для setState заполняет только состояние последнего компонента до состояния родительского компонента при рендеринге - PullRequest
1 голос
/ 04 февраля 2020

У меня есть функция обратного вызова для передачи состояния дочернего компонента в состояние родительских компонентов.

Когда все дочерние компоненты загружаются, я хочу, чтобы они выполнили функцию обратного вызова и заполнили состояние родительского компонента.

Хотя только последний компонент, кажется, передает свое состояние родительскому компоненту.


Мой дочерний компонент:

import React, { useState, useEffect } from "react";

export default function Component(props) {
  const [state, setState] = useState(0);

  useEffect(() => {
    var index = props.index;
    var stateSchema = {};
    stateSchema[index] = state;
    props.updateState(stateSchema);
  }, [state]);

  function onLeftClick() {
    setState(state + 1);
  }

  return <p onClick={onLeftClick}>{state}</p>;
}

Мой родительский компонент:

import React, { useState, useEffect } from "react";
import Component from "./Component";

export default function ParentComponent() {
  const [state, setState] = useState({});

  function updateState(updatedState) {
    setState({
      ...state,
      ...updatedState
    });
  }

  useEffect(() => {
    console.log(state);
  }, [state]);

  return (
    <div>
      <Component index="a" updateState={updateState} />
      <Component index="b" updateState={updateState} />
      <Component index="c" updateState={updateState} />
      <Component index="d" updateState={updateState} />
      <Component index="e" updateState={updateState} />
    </div>
  );
}

В консоли обычно я должен видеть,

Object {e: 0, a: 0, b: 0, c: 0, d: 0}

но я вижу,

Object {}

Object {e: 0}

Вот мой рабочий код: https://codesandbox.io/s/jovial-resonance-f085n?fontsize=14&hidenavigation=1&theme=dark

Буду признателен за любые предложения, заранее спасибо.

1 Ответ

1 голос
/ 04 февраля 2020

setState действия являются асинхронными и пакетируются для увеличения производительности. Это объясняется в документации setState.

setState () не изменяет немедленно this.state, но создает переход состояния ожидания. Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение. Нет гарантии синхронной работы вызовов setState, и вызовы могут быть сгруппированы для увеличения производительности.

Так что в вашей функции updateState, когда она вызывается, состояние еще не было обновлено.

function updateState(updatedState) {
    // state is {}
    setState({
      ...state,
      ...updatedState
    });
  }

Чтобы все заработало, обновите ваш код, как показано ниже:

function updateState(updatedState) {
    setState(prevState => ({
      ...prevState,
      ...updatedState
    }));
  }

Подробнее об этом здесь: https://reactjs.org/docs/react-component.html#setstate

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