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 =&gt; (books: prevState.books.map((book, i) =&gt; if (i === index) return ...book, [link]: value; return book;))) 在这种情况下,您不必使用prevState。 @Titus

以上是关于React - 以动态形式输入 1 个字符后输入失去焦点的主要内容,如果未能解决你的问题,请参考以下文章

React动态形式的输入数组

使用 redux-form 库在 React 中输入字符后失去对输入字段的关注

如何以动态形式使用模型

整数/小数以字符串形式输出

大数加法与大数乘法(字符串形式输入输出)

动态计算输入值 - React