反应更新兄弟组件

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;
      })
    );