В родительском компоненте есть инициализация state
state = {
tasks: {},
users: {
userId: 1,
userName: "Artem Gavrilov",
},
appData: {
selectedDate: new Date(),
unfinished: {},
},
};
Есть дочерний компонент с формой из текстовых инпутов.
export default class Form extends React.Component {
handleTextChange = (e) => {
e.preventDefault();
const {name, value} = e.target;
this.setState({...this.state, appData: {
unfinished: {
[name]: value,
}
}
});
}
render() {
return (
<div className="task-container">
<form className="task-form">
<div className="task-line">
<p className="task-p">Название задачи</p>
<input onChange={this.handleTextChange} className="task-input" type="text" required name="taskName"/>
</div>
<div className="task-line">
<p className="task-p">Описание задачи</p>
<textarea onChange={this.handleTextChange} className="task-textarea" cols="20" rows="5" type="text" required name="taskDesc"/>
</div>
</form>
</div>
);
}
}
Я хочу заполнять объект state.appData.unfinished текущими значениями из инпутов. Проблема в том, что при вводе символов во втором поле - state перезатирается и я теряю значение из первого (и наоборот). Если я записываю в state.[name], все работает корректно, но мне хочется работать с такой структурой состояния. Как перестать перезатирать состояние во вложенном объекте?
В принципе идея в правильном направлении, но есть небольшой нюанс, вот пример с сохранением state
без его перезаписывания:
class Form extends React.Component {
constructor(props) {
super(props);
// засетим значение по-умолчанию, хотя бы пустой объект
this.state = {
appData: {
unfinished: {},
},
};
}
handleTextChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
// сохранение значения в объекте стейта
this.setState(prevState => ({
appData: {
unfinished: {
...prevState.appData.unfinished, // объединяем предыдущее значение с новым значением (копируем объект)
[name]: value, // перезапишем проперти `[name]` в копии объекта `prevState.appData.unfinished`)
}
}
}));
}
showStateToConsole = () => {
console.log(this.state);
}
render() {
return (
<div className="task-container">
<form className="task-form">
<div className="task-line">
<p className="task-p">Название задачи</p>
<input
onChange={this.handleTextChange}
className="task-input"
type="text"
required
name="taskName"
/>
</div>
<div className="task-line">
<p className="task-p">Описание задачи</p>
<textarea
onChange={this.handleTextChange}
className="task-textarea"
cols="20"
rows="5"
type="text"
required
name="taskDesc"
/>
</div>
</form>
<button onClick={this.showStateToConsole}>Show state in console...</button>
</div>
);
}
}
ReactDOM.render(
<Form />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Есть очень хороший пример с массой примеров на enSO: Updating an object with setState in React
Виртуальный выделенный сервер (VDS) становится отличным выбором
Допустим есть строка вида aaaa|qqqq|www|bbbb;ccc Я хочу задать формат в виде $1|$2|$name|$4;$5 И получить объект согласно описанному выше формату с такими же ключамиПодразумевается...
Есть код на для вывода правильной последовательности n элементов, переписал его под python, но он не работаетВ чём моя ошибка?
Когда вызываешь функцию с new, то берется конструктор этой функции и создается объектКак можно вызвать такую функцию так, чтобы она вернула...