Javascript React-是否替换功能组件中的“setState”回调?

Javascript React-是否替换功能组件中的“setState”回调?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我们已经迁移到“反应功能组件”而不是“基于类的组件”。我找不到setState的替代逻辑。也就是说,我有一个带有状态的功能组件,我想创建一个事件处理函数,该函数按顺序多次改变状态,警告是我不知道状态的当前值,它可能是真/假。下面的例子可能更有意义 const Example = () => { const [ openDoor, setOpenDoor ] = useState(false); // the following handler should swich 'open

我们已经迁移到“反应功能组件”而不是“基于类的组件”。我找不到setState的替代逻辑。也就是说,我有一个带有状态的功能组件,我想创建一个事件处理函数,该函数按顺序多次改变状态,警告是我不知道状态的当前值,它可能是真/假。下面的例子可能更有意义

const Example = () => {
  const [ openDoor, setOpenDoor ] = useState(false); 
  // the following handler should swich 'openDoor' state to inverse of
  // current state value. Then after setTimeout duration, inverse it again
  const toggleOpenDoor = () => {
  setOpenDoor(!openDoor);
  // within setTimeout below, '!openDoor' does not work because it still
  // receives the same value as above because of async nature of 
  // state updates
  setTimeout(() => setOpenDoor(!openDoor), 500)
  }
  return(...);
}

在基于类的组件中,我们有一个回调参数,它将在上次更新后更新状态。如何使用状态钩子在上述功能组件中实现相同的功能?

您可以使用useEffect钩子查看状态何时发生更改

useEffect(() => { 
  // do something
  console.log('openDoor change', openDoor)
}, [openDoor]);

您可以使用useEffect挂钩查看状态更改何时发生

useEffect(() => { 
  // do something
  console.log('openDoor change', openDoor)
}, [openDoor]);

我将告诉您,它的工作方式与此基本相同。setState,您只需传递一个回调函数,该函数将前一个状态作为参数并返回新状态

为了让您知道它何时更改,您可以使用useEffect回调,它将在依赖项数组中每次更改时调用


我会告诉你,它的工作原理与此基本相同。setState,只需传递一个回调函数,该函数将前一个状态作为参数并返回新状态

为了让您知道它何时更改,您可以使用useEffect回调,它将在依赖项数组中每次更改时调用


您可以使用useEffect挂钩来实现这一点

setOpenDoor(!openDoor);

useEffect(() => {
   // Here your next setState function
}, [openDoor]);

有关挂钩的更多信息,请查看

您可以使用useEffect挂钩来实现这一点

setOpenDoor(!openDoor);

useEffect(() => {
   // Here your next setState function
}, [openDoor]);
有关挂钩的更多信息,请查看

您应该在useEffect回调中使用setTimeout:

const App = () => {
  const [openDoor, setOpenDoor] = useState(false);

  const toggle = () => setOpenDoor(prevOpen => !prevOpen);

  useEffect(() => {
    const id = setTimeout(() => toggle(), 1000);
    return () => clearTimeout(id);
  }, [openDoor]);

  return <Container>isOpen: {String(openDoor)}</Container>;
};
您应该在useEffect回调中使用setTimeout:

const App = () => {
  const [openDoor, setOpenDoor] = useState(false);

  const toggle = () => setOpenDoor(prevOpen => !prevOpen);

  useEffect(() => {
    const id = setTimeout(() => toggle(), 1000);
    return () => clearTimeout(id);
  }, [openDoor]);

  return <Container>isOpen: {String(openDoor)}</Container>;
};

我想知道useEffect是否是最好的解决方案。特别是当在useEffect中调用setTimeout将导致无限循环时,因为每次调用setOpenDoor时,应用程序都会呈现,然后再次调用useEffect调用setTimeout将调用setOpenDoor函数。。。以图形方式:

setTimeout -> setOpenDoor -> useEffect -> setTimeout -> ... hell  
当然,您可以按照@ksav建议的相同方式使用if语句,但这并不能满足@Kayote的一个要求:

我不知道状态的当前值它可能是真/假

以下是一个解决方案,该解决方案不产生任何效果,并可满足上述要求:

在这里,请参见这段代码的重要性:

const toggleOpenDoor = () => {
  setOpenDoor(!openDoor);
  setTimeout(() => setOpenDoor(openDoor => !openDoor), 500);
};

因为我们使用的是setTimeout,所以需要将回调传递给setOpenDoor,而不是更新状态。这是因为我们要发送“当前”状态。如果我们改为发送新状态,在setTimeOut处理该状态时,它将发生更改,因为我们是在setTimeOut使用setOpenDoor执行回调之前发送的!开门;不会有任何改变

我想知道useEffect是否是最好的解决方案。特别是当在useEffect中调用setTimeout将导致无限循环时,因为每次调用setOpenDoor时,应用程序都会呈现,然后再次调用useEffect调用setTimeout将调用setOpenDoor函数。。。以图形方式:

setTimeout -> setOpenDoor -> useEffect -> setTimeout -> ... hell  
当然,您可以按照@ksav建议的相同方式使用if语句,但这并不能满足@Kayote的一个要求:

我不知道状态的当前值它可能是真/假

以下是一个解决方案,该解决方案不产生任何效果,并可满足上述要求:

在这里,请参见这段代码的重要性:

const toggleOpenDoor = () => {
  setOpenDoor(!openDoor);
  setTimeout(() => setOpenDoor(openDoor => !openDoor), 500);
};

因为我们使用的是setTimeout,所以需要将回调传递给setOpenDoor,而不是更新状态。这是因为我们要发送“当前”状态。如果我们改为发送新状态,在setTimeOut处理该状态时,它将发生更改,因为我们是在setTimeOut使用setOpenDoor执行回调之前发送的!开门;不会有任何改变

我想你可以做一些像setOpenDoor PrevOpenDoor=>这样的事情!PrevOpenDoor我想你可以做像setOpenDoor一样的事情PrevOpenDoor=>!PrevOpenDoor您应该解释如何使用useEffect中的超时作为OP请求。您应该解释如何使用useEffect中的超时作为OP请求。