React.js - input losing focus when rerendering

后端 未结 19 1921
猫巷女王i
猫巷女王i 2020-12-05 01:49

I am just writing to text input and in onChange event i call setState, so React rerenders my UI. The problem is that the text input always lose a f

相关标签:
19条回答
  • 2020-12-05 02:18

    My problem was that I named my key dynamically with a value of the item, in my case "name" so the key was key={${item.name}-${index}}. So when I wanted to change the input with item.name as the value, they key would also change and therefore react would not recognize that element

    0 讨论(0)
  • 2020-12-05 02:20

    My answer is similar to what @z5h said.

    In my case, I used Math.random() to generate a unique key for the component.

    I thought the key is only used for triggering a rerender for that particular component rather than re-rendering all the components in that array (I return an array of components in my code). I didn't know it is used for restoring the state after rerendering.

    Removing that did the job for me.

    0 讨论(0)
  • 2020-12-05 02:21

    Applying the autoFocus attribute to the input element can perform as a workaround in situations where there's only one input that needs to be focused. In that case a key attribute would be unnecessary because it's just one element and furthermore you wouldn't have to worry about breaking the input element into its own component to avoid losing focus on re-render of main component.

    0 讨论(0)
  • 2020-12-05 02:21

    I solved the same issue deleting the key attribute in the input and his parent elements

    // Before
    <input
        className='invoice_table-input invoice_table-input-sm'
        type='number'
        key={ Math.random }
        defaultValue={pageIndex + 1}
        onChange={e => {
            const page = e.target.value ? Number(e.target.value) - 1 : 0
            gotoPage(page)
        }}
    />
    // After
    <input
        className='invoice_table-input invoice_table-input-sm'
        type='number'
        defaultValue={pageIndex + 1}
        onChange={e => {
            const page = e.target.value ? Number(e.target.value) - 1 : 0
            gotoPage(page)
        }}
    />

    0 讨论(0)
  • 2020-12-05 02:22

    For me, this was being caused by the search input box being rendered in the same component (called UserList) as the list of search results. So whenever the search results changed, the whole UserList component rerendered, including the input box.

    My solution was to create a whole new component called UserListSearch which is separate from UserList. I did not need to set keys on the input fields in UserListSearch for this to work. The render function of my UsersContainer now looks like this:

    class UserContainer extends React.Component {
      render() {
        return (
          <div>
            <Route
              exact
              path={this.props.match.url}
              render={() => (
                <div>
                  <UserListSearch
                    handleSearchChange={this.handleSearchChange}
                    searchTerm={this.state.searchTerm}
                  />
                  <UserList
                    isLoading={this.state.isLoading}
                    users={this.props.users}
                    user={this.state.user}
                    handleNewUserClick={this.handleNewUserClick}
                  />
                </div>
              )}
            />
          </div>  
        )
      }
    }
    

    Hopefully this helps someone too.

    0 讨论(0)
  • 2020-12-05 02:24

    The answers supplied didn't help me, here was what I did but I had a unique situation.

    To clean up the code I tend to use this format until I'm ready to pull the component into another file.

    render(){
       const MyInput = () => {
          return <input onChange={(e)=>this.setState({text: e.target.value}) />
       }
       return(
          <div>
             <MyInput />
          </div>
       )
    

    But this caused it to lose focus, when I put the code directly in the div it worked.

    return(
       <div>
          <input onChange={(e)=>this.setState({text: e.target.value}) />
       </div>
    )
    

    I don't know why this is, this is the only issue I've had with writing it this way and I do it in most files I have, but if anyone does a similar thing this is why it loses focus.

    0 讨论(0)
提交回复
热议问题