In React ES6, why does the input field lose focus after typing a character?

前端 未结 10 2099
悲&欢浪女
悲&欢浪女 2020-12-08 12:54

In my component below, the input field loses focus after typing a character. While using Chrome\'s Inspector, it looks like the whole form is being re-rendered instead of ju

相关标签:
10条回答
  • 2020-12-08 13:23

    You have to use a unique key for the input component.

    <input key="random1" type="text" name="displayName" />
    

    The key="random1" cannot be randomly generated. For example,

    <div key={uuid()} className='scp-ren-row'>
    

    uuid() will generate a new set of string for each rerender. This will cause the input to lose focus.

    If the elements are generated within a .map() function, use the index to be part of the key.

    {rens.map((ren,i)=>{
        return(
        <div key={`ren${i+1}`} className='scp-ren-row'>
           {ren}{i}
    </div>)
    }
    

    This will solve the issue.

    0 讨论(0)
  • 2020-12-08 13:24

    My issue was it was rerendering in a stateless component in the same file. So once I got rid of that unecessary stateless component and just put the code in directly, I didn't have unecessary rerenders

    render(){
       const NewSocialPost = () => 
           <div className='new-post'>
               <input
                    onChange={(e) => this.setState({ newSocialPost: e.target.value })}
                    value={this.state.newSocialPost}/>
               <button onClick={() => this._handleNewSocialPost()}>Submit</button>
          </div>
    
    return (
                <div id='social-post-page'>
                    <div className='post-column'>
                        <div className='posts'>
                            <Stuff />
                        </div>
                        <NewSocialPost />
                    </div>
                    <MoreStuff />
                </div>
    
    0 讨论(0)
  • 2020-12-08 13:28

    I'm new to React, and have been running into this issue.

    Here's what I did to solve:

    1. First move all of your components into your components folder and then import them where you want to use them
    2. Make sure all of your form elements get a name and id property
    3. Make sure all components as you walk up the tree get a unique key

    Someone smarter than me can probably tell us why we can skip step one and keep everything inline so to speak, but this just helped me organize the code.

    I think the real issue is React is rerendering everything (as already stated) and sometimes that rerender is happening on a parent component that doesn't have a key but needs one.

    My problem was with ExpansionPanel components wrapping my custom components for form inputs. The panels needed key as well!

    Hope this helps someone else out there, this was driving me crazy!

    0 讨论(0)
  • 2020-12-08 13:34

    it is because you are rendering the form in a function inside render().

    Every time your state/prop change, the function returns a new form. it caused you to lose focus.

    Try putting what's inside the function into your render directly.

           <main id="main" role="main">
                <div className="container-fluid">
                    <FormPostSingle />
                </div>
            </main>
    

    ====>

           <main id="main" role="main">
                <div className="container-fluid">
                    <form onSubmit={onSubmit}>
                        <InputText name="title" label="Title" placeholder="Enter a title" onChange={onChange} value={valueTitle} />
                        <InputSubmit name="Save" />
                    </form>
                </div>
            </main>
    
    0 讨论(0)
  • 2020-12-08 13:35

    I am not authorised to comment then it must be an answer. I had similar issue and Answer from Alex Yan was corect.

    Namely I had that function

    const DisplaySearchArea =()=>{return (arrayOfSearchFieldNames.map((element, index)=>{return(<div key ={index} className = {inputFieldStyle}><input  placeholder= {arrayOfPlaceholders[index]} type="text" className='border-0'
    value={this.state[element]}
    onChange={e => {this.setState({ [element]: e.target.value }); console.log(e.target)}}
    onMouseEnter={e=>e.target.focus()}/></div>)}))}
    

    that behaves OK with FF and not with Chrome when rendered as <DisplaySearchArea /> When render as {...} it's OK with both. That is not so 'beaty' looking code but working, I have already been told to have tendency to overuse lambdas.

    0 讨论(0)
  • 2020-12-08 13:38

    Thanks, Alex. This way I solved my issue:

    constructor(props, context) {
        ...
        this.FormPostSingle = this.FormPostSingle.bind(this);
    }
    FormPostSingle() {
            const onChange = this.onChange;
            const onSubmit = this.onSubmit;
            const valueTitle = this.state.post.title;
            return (
            <form onSubmit={onSubmit}>
                    <InputText name="title" label="Title" placeholder="Enter a title" onChange={onChange} value={valueTitle} />
                    <InputSubmit name="Save" />
                </form>        );
    }
    render() {
        let FormPostSingle = this.FormPostSingle
        return...
    }
    
    0 讨论(0)
提交回复
热议问题