React-将输入属性从defaultValue设置为value会触发无限循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React-将输入属性从defaultValue设置为value会触发无限循环相关的知识,希望对你有一定的参考价值。
我有一个容器组件,其中有一个子组件TranslateForm
(其中有一个表单)和一个子组件AnswersTranslation
。在容器组件中,我有一个函数changeTranslation
,它会随道具一起发送:
async changeTranslation(event, language) {
const translationToUpdate = this.state.translations.find(translation => translation.languageCode === language);
if (event.target.name === 'task') {
translationToUpdate.taskText.to = event.target.value;
} else {
translationToUpdate.answers[event.target.name].to = event.target.value
}
this.setState({translations: this.state.translations.map(translation => translation.languageCode === language ? translationToUpdate : translation)});
this.handleApiCall({...translationToUpdate});
}
handleApiCall(body) {
if (this.timer !== null) {
clearTimeout(this.timer);
}
this.timer = setTimeout(async () => {
this.setState({saving: true});
this.timer = null;
await this.gateway.changeTranslation(body, this.props.match.params);
this.setState({saving: false});
}, 300);
}
而且我像道具一样将其发送下来:
onChange={(event, language) => this.changeTranslation(event, language)}
TranslateForm
具有触发onKeyCapture事件的形式:
<form id={`translate-${translate}`} onKeyUpCapture={event => onChange(event, language)} autoComplete="off">
<AnswersTranslation props={...props} />
</form>
[AnswersTranslation
组件具有一个输入字段,我之前曾像这样设置defaultValue
:
{answers.map((answer, index) => {
<Input
name={`${index}`}
placeholder="Translate..."
className={classes.input}
defaultValue={answers[translate] !== null ? answers[translate] : ''}
disableUnderline={true}
inputProps={{
'aria-label': `answer-tekst-`,
maxLength: 100,
}}
disabled={translate === 'from'}
/>
}
效果很好,但是它没有更新Input字段的值,所以我没有设置defaultValue而是这样设置值:
value={answers[translate] !== null ? answers[translate] : ''}
但是,一旦这样做,我得到了错误:
超过最大更新深度。当一个组件发生这种情况重复调用componentWillUpdate内的setState或componentDidUpdate。 React将嵌套更新的数量限制为防止无限循环。
为什么会这样?
问题可能是因为当您获取translationToUpdate
时,它仍然保留对状态的引用,因此基本上您是在直接对其进行修改。尝试使用setState
的函数形式并调用handleApiCall
作为回调,将从状态中检索值:
async changeTranslation(event, language) {
const { name, value } = event.target;
this.setState(state => ({
translations: state.translations.map(translation => {
if (translation.languageCode === language) {
return name === 'task' ? {
...translation,
taskText: {
...translation.taskText,
to: value
}
} : {
...translation,
answers: {
...translation.answers,
[name]: value
}
}
}
return translation
})
}), () => this.handleApiCall(language)); // Callback after the state is set
}
handleApiCall = (language) => {
const body = this.state.translations.find(translation => translation.languageCode === language);
if (this.timer !== null) {
clearTimeout(this.timer);
}
this.timer = setTimeout(async () => {
this.setState({
saving: true
});
this.timer = null;
await this.gateway.changeTranslation(body, this.props.match.params);
this.setState({
saving: false
});
}, 300);
}
以上是关于React-将输入属性从defaultValue设置为value会触发无限循环的主要内容,如果未能解决你的问题,请参考以下文章
React defaultValue 导致过滤功能的行为与预期不同
react-hook-form 的 DefaultValues 未将值设置为 React JS 中的输入字段