Я пытаюсь динамически визуализировать набор компонентов с помощью componentDidUpdate.
Это мой сценарий:
var index = 0;
class myComponent extends Component {
constructor(props) {
super(props);
this.state = {
componentList: [<ComponentToRender key = {index} id = {index} />]
};
this.addPeriodHandler = this.addPeriodHandler.bind(this);
}
componentDidUpdate = () => {
var container = document.getElementById("container");
this.state.componentList.length !== 0
? ReactDOM.render(this.state.componentList, container)
: ReactDOM.unmountComponentAtNode(container);
};
addHandler = () => {
var array = this.state.componentList;
index++;
array.push(<ComponentToRender key = {index} id = {index} />);
this.setState = {
componentList: array
};
};
render() {
return (
<div id = "Wrapper">
<button id = "addPeriod" onClick = {this.addHandler}>
Add Component
</button>
<div id = "container" />
</div>
);
}
}
Проблема в том, что componentDidUpdate работает только один раз, но он должен работать каждый раз при изменении состояния этого компонента.
Заранее спасибо.
Откуда берутся «компоненты для рендеринга»?
Это компонент, который я импортирую из другой папки
Но что в нем? Отображает ли он какие-либо данные?
Он содержит четыре поля ввода



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


пытаться
addHandler = () =>{
var array = this.state.componentList.slice();
index++;
array.push(<ComponentToRender key = {index} id = {index}/>);
this.setState=({
componentList: array
});
}
если это работает, это проблема с состоянием, содержащим ссылку на массив, которая не изменяется. Когда вы вызываете setState, даже если вы добавили его в массив, он по-прежнему видит ту же ссылку, потому что push не создает новый массив. Возможно, вы сможете использовать тот же массив, если вы также реализуете shouldComponentUpdate и проверите там длину массива нового состояния, чтобы увидеть, изменилось ли оно.
Это не то, как использовать реакцию. С ReactDOM.render() вы создаете совершенно новое дерево компонентов. Обычно вы делаете это только один раз для первоначального рендеринга вашего приложения. Все остальное будет отображаться функциями render() ваших компонентов. Если вы делаете это с ReactDOM.render(), вы в основном отбрасываете все, что уже было обработано, каждый раз, когда вы обновляете свои данные и воссоздаете их с нуля, тогда как на самом деле вам может потребоваться только добавить где-то один узел.
Также то, что вы фактически храните в состоянии компонента, должно быть простыми данными, а не компонентами. Затем используйте эти данные для рендеринга ваших компонентов в функции render().
Пример допустимого варианта использования:
class MyComponent extends Component{
state = {
periods: []
};
handleAddPeriod = () => {
this.setState(oldState => ({
periods: [
...oldState.periods,
{/*new period data here*/}
],
});
};
render() {
return (
<div id = "Wrapper">
<button id = "addPeriod" onClick = {this.handleAddPeriod}>
Add Component
</button>
<div id = "container">
{periods.map((period, index) => (
<ComponentToRender id = {index} key = {index}>
{/* render period data here */}
</ComponentToRender>
))}
</div>
</div>
);
}
}
}
Также вы не должны работать с глобальными переменными, как вы это делали с index. Если у вас есть данные, которые изменяются во время использования вашего приложения, это индикатор, который должен быть состоянием компонента.
Правило №1 клуба React Club: никогда не изменяйте состояние / свойства.