我过去常常使用ref作为表单,但现在我总是声明表单,我面临一个问题,我必须在用户提交后清除字段。
handleSumbit = (e) => {
e.preventDefault()
const todoText = this.state.todoText
if(todoText.length > 0){
this.refs.todoTextElem = "" // wont work
this.props.onAddTodo(todoText)
} else {
this.refs.todoTextElem.focus() //worked
}
}
render() {
return(
<div>
<form onSubmit={this.handleSumbit}>
<input ref="todoTextElem" type="text" onChange={e => this.setState({todoText: e.target.value})} name="todoText" placeholder="What do you need to do?" />
<button className="button expanded">Add Todo</button>
</form>
</div>
)
}
清除参考资料根本不起作用,因为它是受控制的输入。我不想做像
这样的蠢事从父组件传递一个标志,告诉表单已提交,然后使用setState清除输入。或者让onAddTodo进行回调,以便我可以做到
this.props.onAddTodo(todoText).then(()=>this.state({todoText:""}))
答案 0 :(得分:4)
您使用输入元素的方式是uncontrolled,因为您没有使用value属性,意味着不控制它的值。只需将值存储在状态变量中即可。
如果您使用ref,则不需要将输入字段值存储在状态变量中,ref将引用DOM element
,因此您需要使用this.refName.value
访问该元素的值。
<强>步骤:强>
1 - 像这样写输入元素:
<input
ref= {el => this.todoTextElem = el}
type="text"
placeholder="What do you need to do?" />
获取它的价值:this.todoTextElem.value
2 - 要清除不受控制的输入字段,请使用ref清除其值:
this.todoTextElem.value = '';
像这样写:
handleSumbit = (e) => {
e.preventDefault()
const todoText = this.todoTextElem.value;
if(todoText.length > 0){
this.todoTextElem.value = ''; //here
this.props.onAddTodo(todoText)
} else {
this.todoTextElem.focus()
}
}
另一个变化是 string refs, As per DOC :
如果您之前使用过React,那么您可能熟悉旧版本 其中ref属性是字符串的API,例如&#34; textInput&#34;和DOM 节点作为this.refs.textInput访问。我们建议反对它,因为 字符串引用有一些问题,被认为是遗留的,很可能 在将来的一个版本中删除。如果您目前正在使用 this.refs.textInput访问refs,我们建议使用回调模式 代替。
答案 1 :(得分:0)
尝试使用功能参考。请注意,ref是一个DOM元素,这意味着你仍然需要解决它的属性(.value
)来修改它们,而不是试图直接覆盖元素。
以下应该有效:
handleSumbit = (e) => {
e.preventDefault()
const todoText = this.state.todoText
if(todoText.length > 0){
this.todoTextElem.value = ""
this.props.onAddTodo(todoText)
} else {
this.todoTextElem.focus()
}
}
render() {
return(
<div>
<form onSubmit={this.handleSumbit}>
<input ref={input => this.todoTextElem = input} type="text" onChange={e => this.setState({todoText: e.target.value})} name="todoText" placeholder="What do you need to do?" />
<button className="button expanded">Add Todo</button>
</form>
</div>
)
}