[英]React async timing issue, cause modal to pop up with prefilled form after state change?
I have a setCurrentProject call using useState, useEffect hooks api but the modal pops up before the state has been set and it causes the data to throw an error or be blank if i throw in a conditional to check if it's there.我有一个使用 useState 的 setCurrentProject 调用,useEffect 挂钩 api 但模式在 state 设置之前弹出,如果我输入条件以检查它是否存在,它会导致数据抛出错误或为空白。
How do I make sure the state changes before the modal opens with the correct prop data如何确保 state 在使用正确的道具数据打开模态之前发生变化
const EditProjectModal = ({modalOpen, handleClose, addTask, currentProject}) => {
const [name, setName] = useState("");
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState(null);
const [projectTasks, setProjectTasks] = useState([]);
useEffect(() => {
setName(currentProject.name)
setProjectTasks(currentProject.tasks)
setStartDate(currentProject.startDate)
setEndDate(currentProject.endDate)
}, [currentProject])
return(
<Modal
centered={false}
open={modalOpen}
onClose={handleClose}
>
<Modal.Header>Edit Project</Modal.Header>
<Modal.Content>
<Form onSubmit={handleSubmit}>
<Form.Group widths="equal">
<Form.Field
control={Input}
label="Project"
placeholder="Enter the name of your project..."
required
value={name}
onChange={handleName}
/>
</Form.Group>
<Form.Group widths='equal'>
<Form.Field required>
<label>Start Date</label>
<DatePicker
selected={startDate}
onChange={date => setStartDate(date)}
selectsStart
startDate={startDate}
endDate={endDate}
/>
</Form.Field>
<Form.Field required>
<label>End Date</label>
<DatePicker
selected={endDate}
onChange={date => setEndDate(date)}
selectsEnd
startDate={startDate}
endDate={endDate}
minDate={startDate}
placeholderText="Select end date.."
/>
</Form.Field>
</Form.Group>
<ProjectTasksContainer projectTasks={projectTasks} setProjectTasks={setProjectTasks}/>
<Divider hidden/>
<Button type='submit'>Submit</Button>
</Form>
</Modal.Content>
</Modal>
I've left out some of the change functions etc because that's not important to the state change.我省略了一些更改功能等,因为这对 state 更改并不重要。
It's being triggered by a button from another component它是由另一个组件的按钮触发的
const handleEdit = () => {
setCurrentProject(project)
handleEditProjClick();
}
edited to add dashboard that uses the editProjectModal编辑以添加使用 editProjectModal 的仪表板
const Dashboard = ({notes, setNotes, tasks, setTasks, goals, setGoals, projects, setProjects}) => {
//============== STATE VARIABLES ===================//
const [projModalOpen, setProjModalOpen] = useState(false);
const [editProjModalOpen, setEditProjModalOpen] = useState(false);
const [currentProject, setCurrentProject] = useState({});
//============== MODALS ===================//
const handleProjModalOpen = () => {
setProjModalOpen(true);
}
const handleProjModalClose = () => {
setProjModalOpen(false);
}
const handleEditProjModalOpen = () => {
setEditProjModalOpen(true);
}
const handleEditProjModalClose = () => {
setEditProjModalOpen(false);
}
//============== RENDERING FUNCTION ===================//
return (
<Fragment>
<Grid columns={2}>
<Grid.Row stretched>
<Grid.Column width={12}>
<Container style={{width: "90%"}}>
<Segment basic>
<Segment textAlign="right">
<ProjectButton handleClick={handleProjModalOpen}/>
<ProjectModal handleClose={handleProjModalClose} modalOpen={projModalOpen} addTask={addTask} addProject={addProject} />
<EditProjectModal handleClose={handleEditProjModalClose} modalOpen={editProjModalOpen} addTask={addTask} currentProject={currentProject} />
</Segment>
</Container>
</Grid.Column>
<Grid.Column width={4}>
<Segment>
<ProgressContainer projects={projects} handleProjClick={handleProjModalOpen} handleEditProjClick={handleEditProjModalOpen} setCurrentProject={setCurrentProject}/>
</Segment>
</Grid.Column>
</Grid.Row>
</Grid>
</Fragment>
)
}
the parent holds the setCurrentProject state and passes it down to that child and also passes down the handleEditProjClick();父级持有 setCurrentProject state 并将其向下传递给该子级,并向下传递 handleEditProjClick();
What's the best way to handle this issue?处理这个问题的最佳方法是什么?
Cheers!干杯!
Because editProjModalOpen
and currentProject
are independent you could get a situation where editProjModalOpen
is true
and currentProject
is {}
- you'd need to account for that, eg {.isEmpty(currentProject) && <EditProjectModal... /.>}
因为
editProjModalOpen
和currentProject
是独立的,您可能会遇到editProjModalOpen
为true
而currentProject
为{}
的情况 - 您需要考虑这一点,例如{.isEmpty(currentProject) && <EditProjectModal... /.>}
This would then guarantee currentProject
is set in EditProjectModal
and you could just set the initial values in state off the currentProject
:这将保证
currentProject
在EditProjectModal
中设置,您可以在currentProject
中设置 state 中的初始值:
const [name, setName] = useState(currentProject.name);
const [startDate, setStartDate] = useState(currentProject.startDate);
Or if you have to useEffect
then just check the state before rendering the modal:或者,如果您必须使用
useEffect
,则只需在呈现模态之前检查 state:
if (!name ) {
return null
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.