I have to perform the following steps on an array:
- Create an array of refs outside the component
- create a form
- inside the form make a map of the array and render an input for each element
- the input (when in focus) at the press of "enter" puts the next input in focus if there is any, otherwise it submits the form
My code is the following:
const array = new Array(5).fill(createRef());
const Step1 = () => {
return (
<>
{/*Form */}
<form style={{margin:30}} >
{/*- inside the form make a map of the array and render an input for each element, - the input (when in focus) at the press of "enter" puts the next input in focus if there is any, otherwise it submits the form */}
{array.map((item, index) => {
return (
<input
key={index}
ref={item}
type="text"
placeholder={`Input ${index 1}`}
onKeyPress={(e) => {
if (e.key === "Enter") {
if (array[index 1]) {
array[index 1].current.focus();
} else {
e.preventDefault();
console.log("submit");
}
}
}}
/>
);
})}
<button type="submit">Submit</button>
</form>
</>
)
}
export default Step1;
The last point doesn't work, how can I change the code to make it work?
CodePudding user response:
You have two problems. The main problem is your use of Array#fill()
which when used like this fills the array with references to a single object. As such you are ending up with a single ref
which you succesively assigning each input to. The solution is to map the array and return a new ref
on each iteration.
const array = new Array(5).fill(null).map(() => createRef());
// or
const array = Array.from({length: 5}, () => createRef());
Your second problem is that enter
automatically submits the form so you need to preventDefault()
at the top level.
const { createRef } = React;
const array = Array.from({length: 5}, () => createRef());
const Step1 = () => {
function focusNextRef(e, index) {
e.preventDefault();
if (e.key === 'Enter') {
if (array[index 1]) {
array[index 1].current.focus();
} else {
e.preventDefault();
console.log('submit');
}
}
}
return (
<div>
<form style={{ margin: 30 }} >
{array.map((item, index) => {
return (
<input
key={index}
ref={item}
type="text"
placeholder={'Input ' (index 1)}
onKeyPress={(e) => focusNextRef(e, index)}
/>
);
})}
<button type="submit">Submit</button>
</form>
</div>
);
};
ReactDOM.render(
<Step1 />,
document.getElementById('root')
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
@pilchard Thanks, now it functions.