0

I have 5 input fields rendered from an array, when I click on an plus-icon. Now, after I clicked that icon, I want to get a focus on the first of the input fields. How would I realise that? My idea was either with refs, but I don't know how to assign the ref to the first input field only. Or my second idea was, that I can access the input field by key or index somehow. But I don't know how to get the key or index property on the input field because that properties are not shown anywhere. They are also not accessible if I have a reference on the current input field.

actualState.inputFields.map((val,index) => (   
                        <ListElemErrorBoundary key={index}>                   
                            <InputElement  ref={focusInputOnClick}                          
                            key={index} elemValue = {val} name={"input" +  index} onChangeListener={(event) => handleDoublettenIDs(event,index)} />
                        </ListElemErrorBoundary>  
                        )
                    )

2 Answers 2

1

There are many different ways to achieve this but here are possible implementations for each of the two ideas your proposed.

Passing a ref to only the first InputElement :

actualState.inputFields.map((val,index) => (   
                        <ListElemErrorBoundary key={index}>                   
                            <InputElement  ref={(index == 0)?focusInputOnClick:null}                          
                            key={index} elemValue = {val} name={"input" +  index} onChangeListener={(event) => handleDoublettenIDs(event,index)} />
                        </ListElemErrorBoundary>  
                        )
                    )

Keeping track of the different InputElements :

actualState.inputFields.map((val, index) => {
    inputComponent = React.createElement(InputElement, {
        ref: focusInputOnClick,
        key: index,
        elemValue: val,
        name: "input" + str(index),
        onChangeListener: (event) => handleDoublettenIDs(event,index)
    });
    this.inputComponents.push(inputComponent)
    return (<ListElemErrorBoundary key = {index}> 
                 {inputComponent} 
            </ListElemErrorBoundary>)
})

If you only need to focus the first element and nothing more, the first approach might be a better idea as there is no need to keep track of all of the InputElements.

Sign up to request clarification or add additional context in comments.

Comments

0

You can use the ref's function simply to fire the focus:

const InputRow = ({ forwardRef }) => (
  <li><input ref={forwardRef} /><input /></li>
)

class App extends React.Component {
  state = {
    inputs: []
  }
 
  handleRef = ref => {
    ref.focus();
  }
  
  handleAdd = () => {
    this.setState(prevState => (
      { inputs: [...prevState.inputs, 'newInput'] }
    ))
  }
  
  render(){
    const { inputs } = this.state;
    return (
      <div>
        <ul>
          {inputs.map(input => <InputRow forwardRef={this.handleRef} />)}
        </ul>
        <button onClick={this.handleAdd}>Add</button>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

2 Comments

hmm in both cases, it says to me "Cannot read property 'focus' of undefined" is it because I use "useRef" hook in a function component?
If you have some wrapper around the actual input dom element, you should forward the ref. I edited my answer adding the <InputRow /> as example. You cannot use the ref of the react component for focus its child (btw yes, only the Component componetns has ref, the function component has not own ref, but this is not the actual problem here as I see).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.