React控制的组件输入值为空字符串
React controlled component input value with empty string
我在下面为测试React
controlled component
input
特性写了一个演示。但好像有个bug。
class TestComponent extends React.Component{
constructor() {
super();
this.state = {value: 'beef'};
this.handleValueChange = this.handleValueChange.bind(this);
}
handleValueChange(e) {
this.setState({value: e.target.value});
}
render() {
return <div>
<div><input type='text' value={'hello world'} onChange={this.handleValueChange}/></div>
<div><input type='text' value={''} onChange={this.handleValueChange}/></div>
<div><input type='text' value={this.state.value} onChange={this.handleValueChange}/></div>
<div><input type='text' value={null} onChange={this.handleValueChange}/></div>
<div><input type='text' value={undefined} onChange={this.handleValueChange}/></div>
<hr/>
<div><input type='text' defaultValue={this.state.value} onChange={this.handleValueChange}/></div>
<p>{this.state.value}</p>
</div>
}
}
ReactDOM.render(
<TestComponent />,
document.body
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
第一个input
指定字符串值属性。当我输入一些东西时,调用handleValueChange
函数,结果是hello world
+ your type thing's first character
。
第二个input
具有空字符串值属性。当我输入一些东西,它调用handleValueChange
函数,但最后,它总是给我一个字符。
这是奇怪的。
更新!我用defaultValue
添加了input
,与value={this.state.value}
相比,我的头乱了…
正如你的问题下面的评论所提到的:删除value={''}
,因为这会在每次渲染时清空输入。
在react文档中,正确的方法是
return <div>
<input type='text' value={this.state.value} onChange={this.handleValueChange}/>
<p>{this.state.value}</p>
</div>
这样,无论何时在输入区输入内容,都将更新state中的值集。
如果你想让组件的状态中有一个值,你可以使用:
getInitialState() {
return { value: 'Your default value'}
}
或者,如已经建议的,使用defaultValue
。
阅读更多:https://facebook.github.io/react/docs/forms.html
更新:
根据您更新的问题,我认为您必须了解在渲染函数期间设置值的实际作用。无论何时你在渲染函数中设置一个值,你都会将输入字段"锁定"为那个特定的值。这意味着用户输入将不会对呈现的元素产生影响。从文档:"User input will have no effect on the rendered element because React has declared the value"
.
要解决这个问题,你必须将值设置为你可以动态更改的东西,在你的情况下,将是value
或this.state.value
。就像你在第三个例子中所做的那样:
<input type='text' value={this.state.value} onChange={this.handleValueChange}/>
这样,React接受用户输入提供的值,然后更新组件的值。
我仍然认为文档对此规定得非常清楚,我认为您应该阅读我原始回答中提供的文档。
更新2
将controlled
和uncontrolled
组件稍微清理一下:
controlled
组件是一个分配了value
属性的组件,它将反映用户输入的值(value prop
)。
而uncontrolled
组件没有分配任何value
属性,并且不会反映来自用户输入的值(因为它不提供任何value prop
)。但是如果你想用一个值实例化一个uncontrolled
组件,你应该使用defaultValue
。
在您的情况下(因为您尝试使用受控组件),这意味着您不应该使用defaultValue
,并坚持使用controlled
组件的正确实现。这是一个使用value={this.state.value}
的实现。
我再次建议阅读所提供的文档。如果你能理解文档,这其实并不难。
希望这能澄清你的一些问题!:)
用defaultValue
代替value
render() {
return <div>
<div><input type='text' defaultValue={'hello world'} onChange={this.handleValueChange}/></div>
<div><input type='text' defaultValue={''} onChange={this.handleValueChange}/></div>
<div><input type='text' defaultValue={this.state.value} onChange={this.handleValueChange}/></div>
<div><input type='text' defaultValue={null} onChange={this.handleValueChange}/></div>
<div><input type='text' defaultValue={undefined} onChange={this.handleValueChange}/></div>
<p>{this.state.value}</p>
</div>
}
}
这里唯一正确的controlled component
是:
<input type='text' value={this.state.value} onChange={this.handleValueChange}/>
其余的不受控。然而,因为其他的也在调用setState
并改变值,它们会影响第三个输入。
看看会发生什么:
- 第一个输入将用
e.target.value = hello world + first character you typed
调用setState
。这就是第三个输入 的新值 - 第二个输入将只使用一个字符调用
setState
,因为该输入的值始终是''
。所以一个字符将是第三个输入 的新值 - 第四个输入与第二个输入相同
- 最后一次输入,因为值被设置为
undefined
…这和你没有定义任何值是一样的,所以第四个输入不受控制但是每次你输入时它都会将实际值复制到第三个输入
结论:
- 要获得受控输入,总是将值设置为你控制它的变化(状态或道具)。
- 当使用不同的输入改变状态的同一部分时要小心…这真的变得很复杂。
- 如何在字符串输入的 Html 元素中的双引号内编写单引号
- 用于排除.each上的字符串输入的Javascript
- 使用eval使用字符串输入按名称将函数分配给变量有什么风险
- 是否可以创建HTML文本作为文本到语音转换文本字段的字符串输入
- (联合国)通过字符串输入设置嵌套数组值
- 根据字符串输入生成嵌套的 HTML 列表.香草JS
- Ajax 脚本接收用户字符串输入文本并以 JSON 格式发布
- 在mongoDb中,如果字符串输入与任何数组元素匹配,如何获取整个记录(在这种情况下,数组是记录的属性)
- C#.Net从表单帖子中读取字符串输入
- 获取span的每个类的值,并将字符串输入
- 解析并处理作为字符串输入的DOM
- 如何获得字符串输入并将其存储到var中
- Javascript如何接受多个字符串输入并检查是否匹配
- 根据前4个字符串输入字符更改图像
- 字符串输入自动进入只读字段
- Node.js (yargs)数字作为字符串输入
- 带换行符的字符串输入到数组
- 带有字符串输入的If语句
- 根据Javascript中的字符串输入生成唯一的数字
- 与日期字符串输入相关的年龄计算错误