我有一个哑/无状态组件,用于仅渲染表单,
只是一种典型的形式。
import React from 'react'
export const AuthorForm =
({ firstName , lastName , handlefnChange , handlelnChange}) => (
<form action="">
<h2>Manage Authors</h2>
<label htmlFor="firstName">First Name</label>
<input type="text" name="firstName"
value={firstName} onChange={handlefnChange} />
<br/>
<label htmlFor="lastName">Last Name</label>
<input type="text" name="lastName"
value={lastName} onChange={handlelnChange} />
<br/>
<input type="submit" value="save" />
</form>
)
我正在从父智能组件
控制此表单只是渲染上部表单组件向下传递 值和事件处理程序的道具
import React , {Component} from 'react'
import {AuthorForm} from './'
export class ManageAuthors extends Component {
constructor(){
super()
this.state = {
author:{
id: "",
firstName:"",
lastName:""
}
}
}
handlefnChange = e => {
this.setState({
author:{
firstName: e.target.value
}
})
}
handlelnChange = e => {
this.setState({
author: {
lastName: e.target.value
}
})
}
render = () => (
<div>
<AuthorForm
{...this.state.author}
handlefnChange={this.handlefnChange}
handlelnChange={this.handlelnChange} />
</div>
)
}
一切正常,但我收到了这个警告
warning.js:36 Warning: AuthorForm is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://facebook.github.io/react/docs/forms.html#controlled-components
我可以在不转换为stateful
组件的情况下解决此警告吗?
答案 0 :(得分:6)
这是因为当您修改其中任何一个时,作者对象会丢失firstName
或lastName
字段:
handlefnChange = e => {
this.setState({
author: {
firstName: e.target.value
// lastName is missing!
}
});
}
handlelnChange = e => {
this.setState({
author: {
// firstName is missing!
lastName: e.target.value
}
})
}
React仅在this.state
的顶层进行合并。由于firstName
和lastName
嵌套在author
对象中,当您执行handlefn/lnChange
并且只设置其中一个字段时,另一个字段会丢失。
修复方法是:
handlefnChange = e => {
this.setState({
author: {
firstName: e.target.value,
lastName: this.state.author.lastName
}
});
}
handlelnChange = e => {
this.setState({
author: {
firstName: this.state.author.firstName,
lastName: e.target.value
}
})
}
或者如果将来有两个以上的字段,使用spread运算符进行合并会更容易:
handlefnChange = e => {
this.setState({
author: {
...this.state.author,
firstName: e.target.value,
}
});
}
handlelnChange = e => {
this.setState({
author: {
...this.state.author,
lastName: e.target.value
}
})
}
或者使用lodash的实用程序合并功能。