我正在创建一个动态列表组件,该组件基本上会在每次向列表中添加内容时呈现一个新的空文本字段。该组件如下(它使用自定义TextFieldGroup,但我认为代码是不必要的,因为没有任何异常情况发生。):
const DynamicInputList = ({ inputs, onChangeArray, label, name, errors }) =>
{
const nonEmptyInputs = inputs.filter(input => {
return input !== "";
});
const lastIndex = nonEmptyInputs.length;
return (
<div>
{nonEmptyInputs.map((input, index) => {
return (
<Grid container spacing={16} key={index}>
<Grid item xs={12}>
<TextFieldGroup
label={label}
id={`${name}${index}`}
name={name}
value={input}
onChange={e => onChangeArray(e, index)}
errors={errors[name]}
/>
</Grid>
</Grid>
);
})}
<Grid container spacing={16} key={lastIndex}>
<Grid item xs={12}>
<TextFieldGroup
label={label}
id={`${name}${lastIndex}`}
name={name}
value={inputs[lastIndex]}
onChange={e => onChangeArray(e, lastIndex)}
errors={errors[name]}
/>
</Grid>
</Grid>
</div>
);
};
onChangeArray函数如下:
onChangeArray = (e, index) => {
const state = this.state[e.target.name];
if (e.target.value === "") {
state.splice(index, 1);
this.setState({ [e.target.name]: state });
} else {
state.splice(index, 1, e.target.value);
this.setState({ [e.target.name]: state });
}
};
一切正常,除了更改空白字段(开始输入)时,它会立即将焦点从任何字段中移开。我正在寻找一种在保持关注这一领域的同时仍在下面添加新方法的方法。
谢谢。
答案 0 :(得分:1)
问题是您遇到以下事件序列(假设inputs
的长度为5):
至少有两种解决方案
这是更清洁的解决方案。
首先,由于that does an in-place modification,因此您正在使用onChangeArray
直接在slice
中改变状态。也许这现在并没有引起问题,但是它是一个很大的React反模式,可能会导致无法预测的行为。
以下是快速解决方法:
onChangeArray = (e, index) => {
const state = [...this.state[e.target.name]];
if (e.target.value === "") {
state.splice(index, 1);
this.setState({ [e.target.name]: state });
} else {
state.splice(index, 1, e.target.value);
this.setState({ [e.target.name]: state });
}
};
我将把实现的返工交给您,但要旨是:
key
引用,这意味着对所有inputs
进行迭代,而只是跳过空的引用,而不是先查找空的引用并将该任意键设置为总长度。当然,您仍应将 first 设为空。display:none
属性来完成所需的UX input
的{{1}}属性我假设您的autofocus
使用TextFieldGroup
元素。您可以将autofocus
attribute传递到要关注的字段。这回答了您的原始问题。
但是不建议这样做,因为您仍然不需要经历这些重新渲染周期,然后在其顶部放置一个补丁。