admin管理员组文章数量:1387322
I'm creating a dynamic list ponent that basically renders a new empty text field every time something is added to the list. The ponent is as follows (it uses a custom TextFieldGroup but I don't think that code is necessary as nothing out of the ordinary is going on.):
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>
);
};
The onChangeArray function is as follows:
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 });
}
};
Everything works fine except when a blank field is changed (begin to type) it immediately removes focus from any of the fields. I'm looking for a way to keep the focus on this field while still adding the new one below.
Thanks in advance.
I'm creating a dynamic list ponent that basically renders a new empty text field every time something is added to the list. The ponent is as follows (it uses a custom TextFieldGroup but I don't think that code is necessary as nothing out of the ordinary is going on.):
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>
);
};
The onChangeArray function is as follows:
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 });
}
};
Everything works fine except when a blank field is changed (begin to type) it immediately removes focus from any of the fields. I'm looking for a way to keep the focus on this field while still adding the new one below.
Thanks in advance.
Share Improve this question asked Jul 24, 2018 at 20:20 Adam JohnstonAdam Johnston 1,4112 gold badges13 silver badges24 bronze badges 1- please elaborate it.. Everything works fine except when a blank field is changed (begin to type) it immediately removes focus from any of the fields. – Shubham Agarwal Bhewanewala Commented Jul 24, 2018 at 20:54
1 Answer
Reset to default 2The problem is that you're encountering the following sequence of events (assuming inputs
length of 5):
- React renders 1 field (key = 5)
- User starts typing 'a'
- Your state change is triggered
- React renders 2 entirely new fields (key = 1 & value = 'a', key = 5) and trashes the old one (key = 5)
There are at least two solutions
Don't delete / trigger re-render of the original field
This is the cleaner solution.
First, you are directly mutating state in onChangeArray
with your use of slice
, because that does an in-place modification. Perhaps this isn't causing problems now, but it's a big React anti-pattern and could create unpredictable behavior.
Here's a quick fix:
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 });
}
};
And other options
I'll leave the reworking of the implementation to you, but the gist would be:
- Use consistent
key
references, which means iterate over all yourinputs
and just skip the empty ones instead of finding the empty ones first and setting that arbitrary key to the total length. Of course, you should still render the first empty one. - You could consider rendering everything, and use CSS
display:none
attribute as needed to acplish your desired UX
Leverage input
's autofocus
attribute
I assume your TextFieldGroup
uses an input
element. You could pass the autofocus
attribute to the field you want to have focus. This answers your original question.
But this isn't remended, as you're still needlessly running through those re-render cycles and then putting a patch on top.
本文标签: javascriptneed something like eventtargetfocus() in ReactStack Overflow
版权声明:本文标题:javascript - need something like event.target.focus() in React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744569236a2613241.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论