React控制的组件输入值为空字符串

React controlled component input value with empty string

本文关键字:字符串 输入 控制 组件 React      更新时间:2023-09-26

我在下面为测试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" .

要解决这个问题,你必须将值设置为你可以动态更改的东西,在你的情况下,将是valuethis.state.value。就像你在第三个例子中所做的那样:

<input type='text' value={this.state.value} onChange={this.handleValueChange}/>

这样,React接受用户输入提供的值,然后更新组件的值。

我仍然认为文档对此规定得非常清楚,我认为您应该阅读我原始回答中提供的文档。


更新2

controlleduncontrolled组件稍微清理一下:

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…这和你没有定义任何值是一样的,所以第四个输入不受控制但是每次你输入时它都会将实际值复制到第三个输入

结论:

  • 要获得受控输入,总是将值设置为你控制它的变化(状态或道具)。
  • 当使用不同的输入改变状态的同一部分时要小心…这真的变得很复杂。