【问题标题】:react hook for multiple component state didn't update多个组件状态的反应钩子没有更新
【发布时间】:2021-11-12 02:38:19
【问题描述】:

我有一个钩子和 2 个组件。组件App.js有一个函数可以改变hook中的状态,但是组件New.js中的值并没有更新,为什么?我想我错过了一些东西,但无法弄清楚。

App.js

export const useToggle = () => {
  const [onOff, setOnOff] = useState(false);
  return [onOff, () => setOnOff((prev) => !prev)];
};

export default function App() {
  const [onOff, setOnOff] = useToggle();

  return (
    <div className="App">
      <h1>{onOff.toString()}</h1>
      <button onClick={setOnOff}>toggle</button>
    </div>
  );
}

New.js

import { useToggle } from "./App.js";

export default function New() {
  const [onOff] = useToggle();

  return (
    <div className="App">
      <hr />
      <h1>NEW:</h1>
      <pre>{onOff.toString()}</pre>
    </div>
  );
}

https://codesandbox.io/s/musing-fire-rjude?file=/src/App.js

【问题讨论】:

    标签: javascript reactjs ecmascript-6 react-hooks


    【解决方案1】:

    每个useToggle 钩子都是具有自己状态的自己的实体。您在App 中切换的useToggle 与在New 中呈现/使用的useToggle 不同。

    这意味着它们的切换独立于任何其他钩子和状态。他们不共享“状态”。

    如果你想创建一个具有共享状态的 useToggle 钩子,那么我建议通过 React 上下文和 useContext 钩子来实现它,这样每个 useToggle 钩子都可以切换在上下文。

    更新

    全局useToggle钩子。

    togglecontext.js

    import { createContext, useContext, useState } from 'react';
    
    export const ToggleContext = createContext([false, () => {}]);
    
    const ToggleProvider = ({ children }) => {
      const [onOff, setOnOff] = useState(false);
      const toggle = () => setOnOff(t => !t);
    
      return (
        <ToggleContext.Provider value={[onOff, toggle]}>
          {children}
        </ToggleContext.Provider>
      );
    }
    
    export const useToggle = () => useContext(ToggleContext);
    
    export default ToggleProvider;
    

    index - 提供上下文

    ...
    import ToggleProvider from "./toggle.context";
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(
      <StrictMode>
        <ToggleProvider>
          <App />
          <New />
        </ToggleProvider>
      </StrictMode>,
      rootElement
    );
    

    应用程序

    import "./styles.css";
    import { useToggle } from "./toggle.context";
    
    export default function App() {
      const [onOff, setOnOff] = useToggle();
    
      return (
        <div className="App">
          <h1>{onOff.toString()}</h1>
          <button onClick={setOnOff}>toggle</button>
        </div>
      );
    }
    

    新的

    import { useToggle } from "./toggle.context";
    
    export default function New() {
      const [onOff] = useToggle();
    
      return (
        <div className="App">
          <hr />
          <h1>NEW:</h1>
          <pre>{onOff.toString()}</pre>
        </div>
      );
    }
    

    请注意,AppNew 组件中唯一发生变化的是导入,其中定义了 useToggle 挂钩。

    【讨论】:

    • 那怎么分享呢?
    • @alice_morgan 我一定读懂了你的想法,因为我只是将它添加到我的答案中。您需要示例演示吗?
    • 我想知道为什么我需要使用上下文,我只是想与其他组件共享更改的状态,不是那个钩子吗?我知道 useContext 是让内部孩子从多个组件中获取状态,但在我的情况下,我只有 2 个组件,为什么我需要使用上下文?
    • @alice_morgan 不,钩子有多种用途,解决不同的用例。
    • 感谢您的回答!我对其中的2个感到困惑。根据您的经验,在什么情况下您会使用上下文挂钩?说'在多个组件之间共享状态,使用上下文'是否正确?但是钩子不是也允许吗?如果状态需要传递给子组件,只是那个钩子不起作用?
    猜你喜欢
    • 2021-05-19
    • 2020-09-29
    • 1970-01-01
    • 2020-03-09
    • 2021-04-17
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    相关资源
    最近更新 更多