Reputation: 111
I am studying React and Material-ui.
I want to make several input fields within a component, the number and value of these fields are received as props from a parent component. I added a function to move the focus when a user press the Enter button, or create new field if its the last field.
The current code has 15 refs (I know it's stupid, but I think It'll not be more than 15). The problem is that the focus does not move to a new field when it is created. Can you suggest a better way?
class ResponseInput extends Component {
componentWillMount() {
this.refs = [...Array(15)].map(r => React.createRef())
}
changeFocus = index => {
if (index < this.props.inputs.length - 1) {
this.refs[index + 1].current.focus();
} else {
this.props.addInput();
}
}
render() {
const { inputs, addInput, handleChangeInput } = this.props;
return (
<List>
{inputs.map((item, index) => (
<ListItem key={index} >
<Input
value={item}
inputRef={this.refs[index]}
onChange={(event) => handleChangeInput (index, event)}
onKeyPress= {(event) => {
if (event.key === 'Enter') {
this.changeFocus(index);
}
}}
// autoFocus
/>
</ListItem>
))}
</List>
);
}
}
Upvotes: 1
Views: 6234
Reputation: 946
https://codesandbox.io/s/7wojmxv0oq
<Input autoFocus={index+1>originalInputsLength} .../>
Use autoFocus={index+1>originalInputsLength}
checking which means if the input length exceeds original inputs length (user adding the list) then set autoFocus to that newly-created <Input/>
.
originalInputsLength
is initialized in App's constructor as state, then passed down as props to <ResponseInput inputs={inputs} addInput={this.addInput} originalInputsLength={originalInputsLength}/>
class App extends React.Component {
constructor(props){
super(props);
const inputs = [1, 2, 3, 4, 5];
this.state = {
inputs: inputs,
originalInputsLength: inputs.length,
};
}
Upvotes: 1
Reputation: 195992
Adding autoFocus={true}
to the Input
should fix it.
render() {
const { inputs, addInput, handleChangeInput } = this.props;
return (
<List>
{inputs.map((item, index) => (
<ListItem key={index} >
<Input
autoFocus={true}
value={item}
inputRef={this.refs[index]}
onChange={(event) => handleChangeInput (index, event)}
onKeyPress= {(event) => {
if (event.key === 'Enter') {
this.changeFocus(index);
}
}}
// autoFocus
/>
</ListItem>
))}
</List>
);
}
Demo at https://codesandbox.io/s/10089vq54l
Upvotes: 1