Stack Overflow на русском Asked by Node_pro on September 12, 2020
Есть большая форма, в которой куча полей для заполнения. Все работает хорошо, кроме values.defects
. При изменении(добавлении записи) методом push
, React
не перерисовывает элемент. Хотя значение меняется. Единственный вариант, чтобы заставить его реагировать – это клонирования values.defects = [...values.defects];
. В этом случае все работает хорошо. Вопрос: что я делаю не так и можно ли сделать без хака.
React: 16.8.6
Formik: 1.5.1
function addDefect() {
values.defects.push({
key: values.defect_id,
part_name: findPart(values.part_id),
defect_name: findDefect(values.defect_id),
part_id: values.part_id,
});
values.defects = [...values.defects];
setFieldValue('defects', values.defects);
}
Formik:
const enhancedForm = withFormik({
enableReinitialize: true,
mapPropsToValues: props => {
return {
//...
defects: [],
//...
};
},
isInitialValid: false,
handleSubmit: (values) => {
props.onSave(values);
},
displayName: 'ComplaintForm',
});
Вы устанавливаете новое значение, но react не понимает, что необходимо инициализировать перерисовку компонента, т.к. для него ничего не изменилось. Инициализировать его необходимо, используя setState
Читайте подробней про cостояние и жизненный цикл react компонентов
Пример
class Item extends React.Component {
constructor(props) {
super(props)
this.state = {
defects: [],
input: ''
}
}
render() {
return (
<React.Fragment>
<form onSubmit={(e) => {
e.preventDefault();
let defects = this.state.defects.slice()
defects.push(this.state.input)
this.setState({defects, input:''}) //Здесь мы инициализируем перерисовку
}} >
<input type="text"
value={this.state.input}
placeholder="укажите дефект"
onChange={(e)=>{
this.setState({input: e.currentTarget.value})
}}
/>
<input type="submit" action="submit"/>
</form >
<ul>
{this.state.defects.map((d, index)=>(<li key={index}>{d}</li>))}
</ul>
</React.Fragment>
)
}
}
ReactDOM.render(< Item />, document.getElementById('app'))
<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="app"></div>
Answered by xydope on September 12, 2020
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP