反应更新兄弟组件
React update sibling component
我对react热更新组件一头雾水
我有这样的东西:
const SingleEvent = ({ event }) => (
<>{event.status}</>
)
const EventDetails = ({ event, updateEvent }) => (
<button
onClick={async () => {
const data = await getAPIResponse(); // { status: 'open' }
updateEvent(event.id, data)
}
>
Update
</button>
)
const List = ({ events, updateEvent, selectedEvent }) => {
if (selectedEvent) {
return <EventDetails event={selectedEvent} updateEvent={updateEvent} />
}
return (
<>
{events.map(event => <SingleEvent event={event}/>)}
</>
)
}
const Page = ({ initialEvents }) => {
const [events, setEvents] = useState(initialEvents || []);
const [selectedEvent, setSelectedEvent] = useState(null);
const updateEvent = (eventId, data) => {
setEvents(prevState => {
const eventIndex = prevState.findIndex(
element => element._id === eventId,
);
if (eventIndex === -1) {
return prevState;
}
prevState[eventIndex] = {
...prevState[eventIndex],
...data,
};
return prevState;
});
};
return <List events={events} updateEvent={updateEvent} selectedEvent={selectedEvent} />
}
在 <EventDetails />
组件中,我正在更新其中一个事件(基本上是改变它的状态)。如果 API 工作正常,当我关闭详细信息(将 selectedEvent 设置为 null)时,一切都会发生应有的变化。如果我在收到 API 响应之前关闭详细信息 - 什么都没有改变。
我检查了 updateEvent
函数,它正在执行更新,但是 UI 没有刷新。
要明确:
我打开 <EventDetails />
组件,我正在按下按钮来更新事件。 API 应该改变它的状态。当我关闭 EventDetails 时,我得到了一个包含 <SingleEvent />
个组件的列表。他们每个人都显示 event.status
.
如果我在收到响应之前关闭 EventDetails,则 SingleEvent 中的状态不会更新。如果我等待响应,一切正常。
由于在获取数据之前卸载了组件,因此无法再更新响应。
您可以改为提供一个函数作为执行 API 请求并更新状态的 props
const EventDetails = ({ handleClick }) => (
<button
onClick={handleClick}
>
Update
</button>
)
const List = ({ events, updateEvent, selectedEvent }) => {
const handleClick = async () => {
const data = await getAPIResponse(); // { status: 'open' }
updateEvent(event.id, data)
}
if (selectedEvent) {
return <EventDetails event={selectedEvent} updateEvent={updateEvent} handleClick={handleClick}/>
}
return (
<>
{events.map(event => <SingleEvent event={event}/>)}
</>
)
}
问题出在更新方法上。直接在 prevState
上操作不是一个好主意。在我更改 updateEvent
功能后,一切正常。
setEvents(prevState =>
prevState.map(event => {
if (event._id === eventId) {
return {
...event,
...updatedEvent,
};
}
return event;
})
);
我对react热更新组件一头雾水
我有这样的东西:
const SingleEvent = ({ event }) => (
<>{event.status}</>
)
const EventDetails = ({ event, updateEvent }) => (
<button
onClick={async () => {
const data = await getAPIResponse(); // { status: 'open' }
updateEvent(event.id, data)
}
>
Update
</button>
)
const List = ({ events, updateEvent, selectedEvent }) => {
if (selectedEvent) {
return <EventDetails event={selectedEvent} updateEvent={updateEvent} />
}
return (
<>
{events.map(event => <SingleEvent event={event}/>)}
</>
)
}
const Page = ({ initialEvents }) => {
const [events, setEvents] = useState(initialEvents || []);
const [selectedEvent, setSelectedEvent] = useState(null);
const updateEvent = (eventId, data) => {
setEvents(prevState => {
const eventIndex = prevState.findIndex(
element => element._id === eventId,
);
if (eventIndex === -1) {
return prevState;
}
prevState[eventIndex] = {
...prevState[eventIndex],
...data,
};
return prevState;
});
};
return <List events={events} updateEvent={updateEvent} selectedEvent={selectedEvent} />
}
在 <EventDetails />
组件中,我正在更新其中一个事件(基本上是改变它的状态)。如果 API 工作正常,当我关闭详细信息(将 selectedEvent 设置为 null)时,一切都会发生应有的变化。如果我在收到 API 响应之前关闭详细信息 - 什么都没有改变。
我检查了 updateEvent
函数,它正在执行更新,但是 UI 没有刷新。
要明确:
我打开 <EventDetails />
组件,我正在按下按钮来更新事件。 API 应该改变它的状态。当我关闭 EventDetails 时,我得到了一个包含 <SingleEvent />
个组件的列表。他们每个人都显示 event.status
.
如果我在收到响应之前关闭 EventDetails,则 SingleEvent 中的状态不会更新。如果我等待响应,一切正常。
由于在获取数据之前卸载了组件,因此无法再更新响应。
您可以改为提供一个函数作为执行 API 请求并更新状态的 props
const EventDetails = ({ handleClick }) => (
<button
onClick={handleClick}
>
Update
</button>
)
const List = ({ events, updateEvent, selectedEvent }) => {
const handleClick = async () => {
const data = await getAPIResponse(); // { status: 'open' }
updateEvent(event.id, data)
}
if (selectedEvent) {
return <EventDetails event={selectedEvent} updateEvent={updateEvent} handleClick={handleClick}/>
}
return (
<>
{events.map(event => <SingleEvent event={event}/>)}
</>
)
}
问题出在更新方法上。直接在 prevState
上操作不是一个好主意。在我更改 updateEvent
功能后,一切正常。
setEvents(prevState =>
prevState.map(event => {
if (event._id === eventId) {
return {
...event,
...updatedEvent,
};
}
return event;
})
);