React / TypeScript / SPFx forEach и проблемы функций карты со сложными объектами

У меня проблема с рендерингом React с динамическим пользовательским интерфейсом.

Я обнаружил, что один из моих компонентов работает некорректно.

У меня есть объект со свойством массива, который я получаю через реквизиты.

Объект похож на следующий

Obj:

{
  title: "title",
  id: 0,
  rTimes: [
  { idH: 0, hours: 2 }, 
  { idH: 1, hours: 3 }, 
  { idH: 2, hours: 1 }]
};

если я регистрирую объект с помощью console.log (), он показывает правильный результат, но если я повторяю с forEach в массиве часов, это становится странным.

this.props.Obj.rTimes.forEach((rt) => {
  console.log(tr.hours);
});
=== Console Output ===

0
0
0

Для меня это блокирует рендеринг, потому что он передает их на render(), потому что я сопоставляю значения как таковые:

render()
{
    return(
           <div>
           {this.props.Obj.hours.map((h) => 
               <rhourComponent hours={h.hours} />
           )}
           </div>
          );
}

Итак, я получаю 3 компонента с нулевым значением.

Есть идеи, почему это может произойти?

Это клиентская веб-часть React SPFx.


person TheBigCheese    schedule 13.11.2019    source источник
comment
вы можете обновить вопрос своим rhourComponent ? еще раз во время утечки значений в обратном вызове foreach вы получаете итератор как rt и утешительный как tr, это тип вопроса для публикации или опечатка в вашем коде?   -  person Harish    schedule 13.11.2019
comment
Это была опечатка в коде вопроса. Фактический код работает хорошо. Это странно, потому что если я сделаю console.log (rTimes), он покажет мне 3 объекта в массиве, когда я разверну объекты в консоли. Но если я сделаю, например, console.log (Obj.rTimes [1] .hours), он также покажет мне 0.   -  person TheBigCheese    schedule 13.11.2019


Ответы (1)


rTimes объекты, вероятно, обновляются после рендеринга компонента.

Я бы попробовал:

  1. вывод через консоль каждого из объектов массива для проверки, обновляется ли idH;
  2. инкапсулировать forEach в setTimeout;
  3. избегайте использования свойств компонентов непосредственно в JSX, назначая их внутренней переменной компонента и вместо этого отображая этот массив.

Пример (3):

constructor(props) {
  super(props);
  this.state = {
    hours: this.props.Obj.hours
  };
}

А затем на JSX:

<div>
{this.state.hours.map((h) => 
    <rhourComponent hours={h} />
)}
</div>

Или (попутно весь массив):

<div>
    <rhourComponent hours={this.state.hours} />
</div>

Затем вы можете манипулировать hours следующим образом:

this.setState(
  update(this.state, {
    hours: [], // any array you want to change to
  }),
);
person CPHPython    schedule 13.11.2019
comment
Я устанавливаю состояние в основном компоненте и передаю его как свойства. Должен ли я передать реквизиты в состояние дочерних компонентов, а затем использовать это состояние для их дочерних компонентов? Теперь я использовал Object.assign для клонирования объектов перед их передачей, чтобы они не обновляли исходные ссылки. Также у меня есть обратный вызов, который обновляет значения в их текстовых полях в основном компоненте и устанавливает состояние только там. - person TheBigCheese; 13.11.2019
comment
rhourComponent может иметь собственное состояние с часами, установленными в его конструкторе (через пропсы, которые вы передаете). Назначение состояния позволяет избежать проблем с чтением объектов props. Кроме того, при использовании update из immutability-helper все состояние сбрасывается на основе старого состояния, и обновляются только те объекты, которые вы хотите изменить (избегая Object.assign). - person CPHPython; 13.11.2019
comment
Я изучу помощника по неизменяемости. Это может упростить мой код. Я также пытаюсь перенести это на React 16.8, чтобы использовать хуки. Посмотрим, к чему это приведет, потому что все это поведение кажется мне странным. - person TheBigCheese; 14.11.2019