渲染一个引用数组
Render an array of refs
我必须对数组执行以下步骤:
- 在组件外部创建一个引用数组
- 创建表单
- 在表单内创建数组映射并为每个元素呈现一个输入
- 按下“enter”时的输入(当处于焦点状态时)将下一个输入置于焦点状态(如果有的话),否则它会提交表单
我的代码如下:
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;
最后一点不起作用,我怎样才能更改代码使其起作用?已解决
唯一的问题是我无法在输入中写入。已解决
如果我想使用通过 forwardRef 获取 ref 的输入组件。
你有两个问题。主要问题是您使用 Array#fill()
,当像这样使用时,它会用对单个对象的引用填充数组。因此,您最终得到一个 ref
,您将每个输入连续分配给它。解决方案是在每次迭代时映射数组和 return 一个新的 ref
。
const array = new Array(5).fill(null).map(() => createRef());
// or
const array = Array.from({length: 5}, () => createRef());
您的第二个问题是 enter
自动提交表单,因此您需要 preventDefault()
在 if
块的顶层。
const { createRef } = React;
const array = Array.from({length: 5}, () => createRef());
const Step1 = () => {
function focusNextRef(e, index) {
if (e.key === 'Enter') {
e.preventDefault(); // <-- move preventDefault()
if (array[index + 1]) {
array[index + 1].current.focus();
} else {
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>
我必须对数组执行以下步骤:
- 在组件外部创建一个引用数组
- 创建表单
- 在表单内创建数组映射并为每个元素呈现一个输入
- 按下“enter”时的输入(当处于焦点状态时)将下一个输入置于焦点状态(如果有的话),否则它会提交表单
我的代码如下:
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;
最后一点不起作用,我怎样才能更改代码使其起作用?已解决
唯一的问题是我无法在输入中写入。已解决
如果我想使用通过 forwardRef 获取 ref 的输入组件。
你有两个问题。主要问题是您使用 Array#fill()
,当像这样使用时,它会用对单个对象的引用填充数组。因此,您最终得到一个 ref
,您将每个输入连续分配给它。解决方案是在每次迭代时映射数组和 return 一个新的 ref
。
const array = new Array(5).fill(null).map(() => createRef());
// or
const array = Array.from({length: 5}, () => createRef());
您的第二个问题是 enter
自动提交表单,因此您需要 preventDefault()
在 if
块的顶层。
const { createRef } = React;
const array = Array.from({length: 5}, () => createRef());
const Step1 = () => {
function focusNextRef(e, index) {
if (e.key === 'Enter') {
e.preventDefault(); // <-- move preventDefault()
if (array[index + 1]) {
array[index + 1].current.focus();
} else {
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>