javascript 为什么这个setState没有触发

wfypjpf4  于 2023-01-04  发布在  Java
关注(0)|答案(1)|浏览(144)

我正在尝试为我的应用程序构建一个通知React组件,我可以从任何地方调用它。我有下面的代码,我正在尝试做一些导出showNotif函数的技巧。

function FloatNotification() {
  const [show, setShow] = useState(false);

  const showNotif = () => {
    console.log(`showNotif is called`);
    setShow(true);
  };

  if (!FloatNotification.showNotification) {
    FloatNotification.showNotif = showNotif;
  }

  return <>{show ? `Showing notification` : `not showing notification`}</>
}

export default FloatNotification;

在另一个文件中,我尝试调用showNotif,如下所示

import FloatNotification from "./FloatNotification";

function MyComponent() {
  const {showNotif} = FloatNotification;
  return <><button onClick={() => showNotif()}>Click Me</button></>
}

但是setState没有被意外调用。我在控制台中得到showNotif is called消息。所以逻辑上setState也应该被调用。
我有点理解它的发生是因为javascript处理引用数据类型的方式,但是我不确定幕后到底发生了什么,以及如何实现我的目标
如果您有任何其他想法来构建这个通知组件(我可以从组件树中的任何位置调用它),请向我建议。任何帮助都将是我的荣誉
[NOTE:我实际上使用的是NextJS,我在_app.js中添加了这个FloatNotification,所以它在所有页面中都可用

vql8enpb

vql8enpb1#

useState是一个叫做“hooks”的特殊函数,只有在VDOM树中呈现组件时,React hooks才可用。
由于您没有将FloatNotification呈现为元素,因此调用setState是意外的,可能没有任何效果。
有几种方法可以达到你想要的没有黑客。
首先,将通知状态提升到父组件,并仅通过上下文注入改变状态的调度。

const NotificationContext = React.createContext(() => {});

function FloatNotification({ children }) {
  const [show, setShow] = useState(false);

  return (
    <NotificationContext.Provider value={setShow}>
      {children}
      <>{show ? `Showing notification` : `not showing notification`}</>
    </NotificationContext.Provider>
  );
}

function MyComponent() {
  const setShow = useContext(NotificaitonContext);
  return (
    <button onClick={() => setShow(true)}>
      Show Notification
    </button>
  );
}

function App() {
  return (
    <FloatNotification>
      <MyComponent />
    </FloatNotification>
  );
}

或者,可以通过React.useImperativeHandle公开处理程序(通常不推荐)

相关问题