React - 以动态形式输入 1 个字符后输入失去焦点
Posted
技术标签:
【中文标题】React - 以动态形式输入 1 个字符后输入失去焦点【英文标题】:React - Input loses focus after typing 1 char in dynamic form 【发布时间】:2019-12-28 04:35:32 【问题描述】:我正在尝试创建一个动态表单,在此表单中,用户可以添加任意数量的书籍,并且每本书都有一个名称和一个链接。
我已经有一个按钮添加一本书,并且在我的表单中正确添加了字段,但是当我输入这些字段中的任何一个时,我的输入失去了焦点
我将books []
保存在我的组件状态中,为了更新它,我的输入中有一个onChange=(e) => this.handleDynamicChange(e, 'fieldName', index)
。
handleDynamicChange
handleDynamicChange = (event, name, index) =>
const value = event.target;
let books = this.state;
books[index][name] = value;
this.setState( books );
我对书籍链接的输入(使用材料 ui):
<TextField
id=`edit-profile-book-link-$index`
label='Link'
value=book.link
onChange=(e) => this.handleDynamicChange(e, 'link', index)
/>
我想这是因为我正在更新整个书籍数组,所以 react 正在重新渲染所有书籍字段,但是我找不到使用 setState()
只更新一本书的方法,所以,你知道怎么做在动态表单中处理这些更新?
我已经看到了这个问题,但没有帮助: React.js - input losing focus when rerendering
我一直在查看本教程: building a dynamic controlled form
【问题讨论】:
我不确定这是否会有所帮助,但通常你应该在循环内的***组件上拥有一个独特的key
道具。如果您的 TextField
在循环内,请添加类似 key=i
从您发布的代码中看不出问题,它似乎工作得很好,这是一个例子codesandbox.io/embed/material-demo-iqdmg
谢谢,密钥解决了我的问题,我已经添加了一个随机密钥,但是如果密钥发生变化,输入就会失去焦点。使用索引就可以了。
【参考方案1】:
let books = this.state;
books[index][name] = value;
你在这里改变状态,你不应该直接操纵状态。推荐的做法是使用the spread operator
。
this.setState( books: [...this.state.books,
this.state.books[index]: ...this.state.book[index], this.state.books[index][name]: value
] )
【讨论】:
books
是一个数组,推荐的方法是不使用 扩展运算符,而是使用接收前一个状态作为参数的函数调用 setState
。
不,最短的方法是使用展开运算符。没有它你也能达到同样的效果,但它很长。所以推荐的方法是使用扩展运算符。 @Titus
那还是不行,应该是这样的:this.setState(prevState => (books: prevState.books.map((book, i) => if (i === index) return ...book, [link]: value; return book;)))
在这种情况下,您不必使用prevState
。 @Titus以上是关于React - 以动态形式输入 1 个字符后输入失去焦点的主要内容,如果未能解决你的问题,请参考以下文章