javascript - 如何在 React JS 中动态添加子数组输入字段
问题描述
这是我的代码
const useStyles = makeStyles((theme) => ({
root: {
'& .MuiTextField-root': {
margin: theme.spacing(1)
},
},
button: {
margin: theme.spacing(1)
}
}))
function CreateCourse() {
const classes = useStyles();
const [sectionFields, setSectionFields] = useState([{
sectionName: '',
overview: '',
videoContents: [{
videoName: '', videoUrl: ''
}]
}])
function handleChangInput(index, event) {
const values = [...sectionFields];
values[index][event.target.name] = event.target.value;
setSectionFields(values);
}
function handleChangVideoInput(index, i, event) {
const values = [...sectionFields];
values[index].videoContents[i][event.target.name] = event.target.value;
setSectionFields(values);
console.log(index, event.target.name)
}
const handleSubmit = (event) => {
event.preventDefault();
console.log("Input Field ", sectionFields)
}
const handleRemoveFields = (index) => {
const values = [...sectionFields];
values.splice(index, 1)
setSectionFields(values)
}
const handleAddFields = () => {
setSectionFields([...sectionFields, {
sectionName: '',
overview: '',
videoContents: [{videoName: '', videoUrl: ''}]
}])
}
return (
<div className='container mb-5'>
<Container>
<h1>Add New Member</h1>
<form className={classes.root} onSubmit={handleSubmit}>
{sectionFields.map((inputField, index) => (
<div key={index}>
<TextField
name="sectionName"
label="Section Name"
variant="filled"
value={inputField?.sectionName}
onChange={event => handleChangInput(index, event)}
/>
<TextField
name="overview"
label="Section Overview"
variant="filled"
value={inputField?.overview}
onChange={event => handleChangInput(index, event)}
/>
<IconButton onClick={() => handleRemoveFields(index)}>
<RemoveIcon/>
</IconButton>
<IconButton onClick={handleAddFields}>
<AddIcon/>
</IconButton>
{inputField?.videoContents?.map((v, i) => (
<div key={i}>
<TextField
name="videoName"
label="Enter Video Name"
variant="filled"
value={v.videoName}
onChange={event => handleChangVideoInput(index, i, event)}
/>
<TextField
name="videoUrl"
label="Enter Video Url"
variant="filled"
value={v.videoUrl}
onChange={event => handleChangVideoInput(index, i, event)}
/>
</div>
))}
</div>
))}
<Button
className={classes.button}
variant='contained'
color='primary'
type='submit'
endIcon={<Icon/>}
onClick={handleSubmit}
>
SEND
</Button>
</form>
</Container>
</div>
);
}
export default CreateCourse;
屏幕截图中的输出
当我单击加号图标时,会创建一个新输入,例如
但是我想要一个 sectionName 有很多 videoName 和 videoUrl 就像我想在 videoUrl 一侧创建加号图标,当用户单击加号图标时,它会根据用户的需要创建许多 videoName 和 videoUrl,如果用户单击部分,那么它会创建一个部分行一个视频行。如何使用反应解决这个问题?
解决方案
首先,当您使用状态的当前值来计算新的状态值时,最好使用回调函数。这样它就不会受到重新渲染的影响,并保证计算使用最新的状态值。
所以假设你有
const [state, setState] = useState([]);
不要使用:
const next = [...state, newElement];
setState(next);
但是,请使用:
setState((previous) => [...previous, newElement]);
为了将更多字段添加到嵌套数组中,您可以像这样更新状态:
function addToSection(i) {
setSectionFields((prev) => (
const updatedSection = {
...prev[i],
videoContents: [
...prev[i].videoContents,
{ videoName: '', videoUrl: '' },
],
};
return prev.map((section, index) => {
return index === i ? updatedSection : section;
});
);
}
推荐阅读
- android - Android 应用和 Xamarin.Forms 中的启动器图标
- websphere-liberty - 自由 18.0.0.3 中的 JPA2 使用 MySQL 数据库
- git - 默认为 git push
- r - R - Split time series into colums depending on weekday
- android - Firebase 执行代码 IF 子级已创建
- c++ - Send an array of Characters as a parameter to a function in C ++
- r - Identify rows which are lowering the correlation coefficient in R
- html - Hide overflow of an image with a greater width than the body
- python - heapq custom compareTo
- oracle - Issues with selection of DATES between START and END dates