React不会在自定义挂钩中重新渲染状态更新时的所有组件

时间:2020-03-17 08:19:39

标签: javascript reactjs react-hooks

我已经创建了两个组件C1C2和一个custom hook useCounter。

C1显示"count"的{​​{1}}属性。

useCounter hook显示C2属性,并在单击按钮时增加或减少该属性。

"count"更改Current behavior:时,更新的值仅显示在"count"中,而不显示在C2中。

C1两个组件都应在Expected behavior:更新中re-render

请让我知道我是否缺少任何东西。

"count"我已经使用PS:Context API完成了此操作。只想知道是否可以使用redux来实现相同的行为:)

custom hooks Custom hooks demo

Codesandbox link:

3 个答案:

答案 0 :(得分:2)

您可能希望使用Context API共享同一实例,因为自定义钩子useCounter将在挂载时分配count的新实例:

export const CounterContext = React.createContext();

function App() {
  const counterController = useCounter();
  return (
    <CounterContext.Provider value={counterController}>
      <div className="App">
        <h1>App Component</h1>
        <hr />
        <C1 />
        <hr />
        <C2 />
      </div>
    </CounterContext.Provider>
  );
}

// Use context
function C1() {
  const [count] = useContext(CounterContext);
  return (
    <div>
      Component 1 <br />
      Count: {count}
    </div>
  );
}

Edit nostalgic-hypatia-by6s4


此外,您可以使用类似reusable的库:

const useCounter = createStore(() => {
  const [counter, setCounter] = useState(0);

  return {
    counter,
    increment: () => setCounter(prev => prev + 1)
  }
});

const Comp1 = () => {
  const something = useCounter();
}

const Comp2 = () => {
  const something = useCounter(); // same something
}

答案 1 :(得分:1)

嘿,我完全同意@RVRJ的解释。因此,当您导入任何挂钩时会发生什么,它将创建该挂钩的新对象。假设在两个不同的文件中导入相同的钩子,这意味着您将创建该钩子的两个不同的对象。

在这里,我试图仅使用钩子来解决您的问题,但是我仅导入了一次钩子,并将其对象传递给子组件<C1 /> and <C2 />

以下是我创建 useCounter 钩子

的单个对象的示例
import React from "react";
import C1 from "./components/C1";
import C2 from "./components/C2";
import useCounter from "./hooks/useCounter";

function App() {
  const [count, updateCount] = useCounter(); // <<-- created one object

  return (
    <div className="App">
      <h1>App Component</h1>
      <hr />
      <C1 count={count} updateCount={updateCount} /> {/* passing values ad props */}
      <hr />
      <C2 count={count} updateCount={updateCount} /> {/* passing values ad props */}
    </div>
  );
}

export default App;

现在,您可以在每个孩子中使用 count updateCount 作为道具。

更改后为C1组件

// C1 component

 import React from "react";

 function C1({ count }) { {/* <-- access count as props */}
   return (
     <div>
       Component 1 <br />
       Count: {count}
     </div>
   );
 }
 export default C1;

这是您的C2组件

// C2 component
import React from "react";

function C3({ count, updateCount }) { {/* <-- access count and as updateCount props */}
  const handleIncr = () => {
    updateCount(count + 1);
  };
  const handleDecr = () => {
    updateCount(count - 1);
  };
  return (
    <div>
      Component 2 <br />
      <button onClick={handleIncr}>Increment</button>
      <button onClick={handleDecr}>Decrement</button>
      <br />
      <br />
      <br />
      Count: {count}
    </div>
  );
}
export default C3;

这里更新了您的问题https://codesandbox.io/s/romantic-fire-b3exw的有效解决方案

注意:我不知道对相同状态值使用钩子的用例是什么,因此我仍然建议您使用 redux 在组件之间共享状态。

答案 2 :(得分:0)

两个组件是否使用相同的Hook共享状态?否。自定义Hook是一种可重用有状态逻辑的机制(例如设置订阅并记住当前值),但是每次使用时自定义钩子,其中的所有状态和效果都完全隔离。

Using a Custom Hook中引用第3点


它们不是共享状态的方法,而是共享有状态逻辑的方法。我们不想破坏自上而下的数据流!

参考:Making Sense of React Hooks