Через my previous question я узнал, что React сохраняет состояние для дочерних компонентов автоматически и поэтому its documentation says:Как сохранить состояние для «просто» скрытого компонента
Что Не должен Go в штате?
Реактивные компоненты: Построить их в render() на основе базовых опор и состояния.
Теперь мой вопрос заключается в том, как сделать то же самое для компонентов, которые мы только скрываем?
Рассмотрите дочерний компонент, который на итерации не будет показан, и в то же время мы хотели бы сохранить его состояние в будущем, когда оно будет возвращено!
Чтобы проиллюстрировать, что я точно имею в виду, я разработал сценарий случая, чтобы показать его вам. В следующем коде вы можете добавить дочерние компоненты с состоянием. Для каждого компонента предоставляется флажок, чтобы вы могли их отмечать. Наконец, третья кнопка будет скрыть дочерние компоненты, которые не помечены. Я ищу способ восстановить состояние для не помеченных компонентов, как только они будут возвращены.
class BlackBox extends React.Component
{
constructor() {
super();
this.state = {
checked: false,
counter: 0,
};
}
increment =() => {
this.setState(Object.assign({}, this.state, { counter: this.state.counter+1 }));
};
switch =() => {
this.setState(Object.assign({}, this.state, { checked: !this.state.checked }));
};
isChecked() {
return this.state.checked;
}
render() {
return (
<span onClick={this.increment} title={this.props.id} style={{
fontSize: '24pt',
border: '1px solid black',
margin: 10,
padding: 10,
}}>
<input type="checkbox" onChange={this.switch} checked={this.state.checked} />
{this.state.counter}
</span>
);
}
}
class RedBox extends React.Component
{
constructor() {
super();
this.state = {
checked: false,
counter: 0
};
}
increment =() => {
this.setState(Object.assign({}, this.state, { counter: this.state.counter+1 }));
};
switch =() => {
this.setState(Object.assign({}, this.state, { checked: !this.state.checked }));
};
isChecked() {
return this.state.checked;
}
render() {
return (
<span onClick={this.increment} title={this.props.id} style={{
fontSize: '24pt',
border: '1px solid red',
margin: 10,
padding: 10,
}}>
<input type="checkbox" onChange={this.switch} checked={this.state.checked} />
{this.state.counter}
</span>
);
}
}
class Parent extends React.Component {
static blackCount = 0;
static redCount = 0;
state = {
childCmps: [],
showOnlyChecked: false,
};
constructor(props, context) {
super(props, context);
}
addBlackBox =() => {
this.setState(Object.assign({}, this.state, {
childCmps: [...this.state.childCmps, { Component: BlackBox, id: "black" + (++Parent.blackCount) }],
}));
};
addRedBox =() => {
this.setState(Object.assign({}, this.state, {
childCmps: [...this.state.childCmps, { Component: RedBox, id: "red" + (++Parent.redCount) }],
}));
};
showHide =() => {
this.setState(Object.assign({}, this.state, {
showOnlyChecked: !this.state.showOnlyChecked,
}));
};
render() {
let children = this.state.childCmps.map(child => <child.Component key={child.id} id={child.id} ref={child.id} />);
return (
<div>
<button onClick={this.addBlackBox}>Add Black Box</button>
<button onClick={this.addRedBox}>Add Red Box</button>
<button onClick={this.showHide}>Show/Hide Unchecked</button>
<br /><br />
{children.filter(box => !this.state.showOnlyChecked || this.refs[box.props.id].isChecked())}
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById("root")
);
Я понимаю ваши рассуждения, но что, если состояние ребенка сложное с множеством внутренних состояний? Я имею в виду, как иметь внуков и прочее? Хранение данных в глобальном масштабе (например, в магазинах) усложняет работу, не так ли? – Mehran
Нет решения, которое имеет только преимущества и недостатки (как в реальной жизни, так и в вашем вопросе). У вас действительно есть только 3 варианта: a) использовать родительское состояние и управлять своими данными; b) использовать дочернее состояние и скрыть детей, которые вам не нужны (так что найти другое решение для анимации); c) использовать дочернее состояние и принять, что это состояние потеряно для детей не перерисовываться - вы могли бы использовать магазины хорошо, вы можете проверить редукс. – wintvelt
Вы должны были разместить это – Mehran