ReactJS: неверное отображение списка компонентов - PullRequest
0 голосов
/ 25 октября 2018

У меня есть компонент («ComponentA»), который отображается несколько раз в map () внутри render () другого компонента («ComponentB»).

Кроме того, у меня есть «ADD»кнопка в ComponentB, которая при щелчке предварительно ожидает (с помощью метода unshift ()) объект в массиве своего компонента ComponentB «state.objects» (используется для отображения экземпляров ComponentA).Каждый предварительно созданный объект имеет свойство 'prop1', с помощью которого я устанавливаю входное текстовое значение ComponentA.

Проблема в том, что я не получал ожидаемые значения в состоянии каждого экземпляра ComponentA: во всех случаях элемент всегдаимеет значение '1' (я ожидаю ... 3, 2, 1).

Более того, я вижу, что конструктор ComponentA вызывается только один раз в каждом цикле отображения, а именно перед вызовом render ()для последнего экземпляра.

Вот (упрощенный) код:

    class ComponentB extends Component {
      constructor(props) {
        super(props) // added upon first reply
        this.handleObjectAdd = this.handleObject.bind(this);
        this.state.objects = [];
      }

      handleObjectAdd() {
        this.state.objects.unshift({prop1: this.state.objects.length + 1});
      }

      render() {
          return (
            <div>
              <button onClick={this.handleObjectAdd}>ADD</button>
              { this.state.objects.map((object, index) =>
                  <ComponentA key={index} details={object}/>
                )
              }
            </div>
          )
        })
      }
    }

    class ComponentA extends Component {
      constructor(props) {
        super(props) // added upon first reply
        console.log('ComponentA constructor called');
        this.state = { details: props.details };
      }
      render() {
        console.log('ComponentA render() called, prop1 value is ' + this.state.details.prop1);
        return (
          <input type="text" value={this.state.details.prop1}></input>
        )
      }
    }

Таким образом, с помощью приведенного выше кода нажатие кнопки ADD один раз регистрирует следующее:

    ComponentA constructor called
    ComponentA render() called, prop1 value is 1

Нажатие на кнопку 2-й раз регистрирует:

    ComponentA render() called, prop1 value is 1
    ComponentA constructor called'
    ComponentA render() called, prop1 value is 1

Нажатие на кнопку 3-й раз регистрирует:

    ComponentA render() called, prop1 value is 1
    ComponentA render() called, prop1 value is 1
    ComponentA constructor called'
    ComponentA render() called, prop1 value is 1

... и т. Д.

Во всех экземплярах ComponentA входное текстовое значение равно "1".

Мои вопросы:

1) Как мне его кодировать, чтобы получить желаемое увеличивающееся значение, отображаемое для ComponentA?

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

ПРИМЕЧАНИЕ. Приведенный выше код является просто упрощенной версией моего фактического кода, показывая только основные части, демонстрирующие проблему.

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Исправлена ​​проблема, связанная с использованием этого кода:

    <input value={this.props....} onChange={...} // first version

вместо

    <input value={this.state....} onChange={....} // second version

Ранее я считал, что вторая версия верна и что первая версия препятствовалаВвод от того, чтобы быть редактируемым.Но, похоже, присутствие на onChange заставило работать первую версию (правильно отображая начальные и отредактированные значения и позволяя редактировать)

0 голосов
/ 25 октября 2018

Вы никогда не должны изменять состояние напрямую , делая что-то вроде this.state.objects.unshift() - вместо этого используйте this.setState().Когда вы изменяете массив или объект внутри this.state напрямую, React не знает, что какое-то значение внутри него было изменено.Это отвечает на оба ваших вопроса.Таким образом, вместо непосредственного изменения this.state.objects:

this.state.objects.unshift({prop1: this.state.objects.length + 1});

следует добавить новый элемент к массиву неизменным образом:

const newItem = { prop1: this.state.objects.length + 1 };
this.setState({
  objects: [newItem].concat(this.state.objects)
});

Кроме того, вы забыли вызватьsuper(props) внутри конструкторов ComponentA и ComponentB.Также нет необходимости копировать переданные реквизиты в состояние компонентов внутри ComponentA - просто используйте реквизиты.Вы можете увидеть рабочие коды и коробки здесь .

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