代码之家  ›  专栏  ›  技术社区  ›  Boris Traljić

意外(?)可重用的react hook函数的行为,或者我做错了什么?

  •  1
  • Boris Traljić  · 技术社区  · 6 年前

    我正在尝试编写自己的可重用useeffect hook函数 useEffectOnce() 只运行一次(安装和卸载),但似乎不可能。每次重新呈现后调用我的函数: https://codesandbox.io/s/mjx452lvox

    function useEffectOnce() {
      console.log("I am in useEffectOnce");
    
      useEffect(() => {
        console.log("I am in useEffectOnce's useEffect");
        return () => {
          console.log("i am leaving useEffectOnce's useEffect");
        };
      }, []);
    }
    
    function App() {
      const [count, setCount] = useState(0);
    
      useEffectOnce(); // once!?
    
      return (
        <div className="app">
          <h3>useEffectOnce (my reusable function)... Wait, once!?</h3>
          <button onClick={() => setCount(count + 1)}>
            You clicked me {count} times
          </button>
        </div>
      );
    }
    

    笔记:

    • useEffectOnce()内的useEffect()挂钩按预期工作
    • useEffectOnce(() => {}, []); 什么也不改变

    …然后让人大吃一惊,同样的行为与可重用的usestate hook函数(!?) https://codesandbox.io/s/2145m37xnr

    我的功能 useButton 在每次重新渲染后调用,并在第一次单击独立按钮时调用。

    function useButton(initialCounterValue) {
      const [usebuttoncount, setUseButtonCount] = useState(initialCounterValue);
    
      console.log("I am in useButton");
    
      const handleuseButtonClick = () => {
        setUseButtonCount(usebuttoncount + 1);
      };
    
      return {
        usebuttoncount,
        onClick: handleuseButtonClick
      };
    }
    
    function App() {
      const [count, setCount] = useState(0);
      const useButtonCounter = useButton(0);
    
      return (
        <div className="app">
          <h3>
            useButton (my reusable useState function) is called only when... OMG!?
          </h3>
          <button onClick={() => setCount(count + 1)}>
            You clicked me {count} times
          </button>
          <br />
          <button {...useButtonCounter}>
            (useButton hook) You clicked me {useButtonCounter.usebuttoncount} times
          </button>
        </div>
      );
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Estus Flask    6 年前

    useEffectOnce useButton 是常规功能。它们应该在每个组件渲染上运行。当调用组件函数时,没有办法阻止它们被常规的javascript方法调用(即不使用 eval )

    它是 useEffect 回调函数( I am in useEffectOnce's useEffect 日志项),在组件装入时应该调用一次。所有需要在组件装入时评估的代码都应该驻留在那里。