【问题标题】:useImperativeHandle hook does not update the valueuseImperativeHandle 钩子不更新值
【发布时间】:2021-04-01 00:12:02
【问题描述】:

我在我的应用程序中使用 useImperativeHandle 钩子来为父组件提供值访问权限:

const [phone,setPhone]=useState("");
 useImperativeHandle(
    ref,
    () => ({
      type: "text",
      name: "phone",
      value: phone
    }),
    [phone]
  );

当我使用 setPhone 更新手机时,值不会更新。我的实现有什么问题?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    useImperativeHandle 需要让组件使用 forwardRef,一旦这样做,您将能够访问父级中更新的 ref,因为您提供了 phone 作为对它的依赖项。

    import React, {
      useEffect,
      useState,
      useImperativeHandle,
      forwardRef,
      useRef
    } from "react";
    import ReactDOM from "react-dom";
    
    import "./styles.css";
    
    const App = forwardRef((props, ref) => {
      const [phone, setPhone] = useState("");
      useImperativeHandle(
        ref,
        () => ({
          type: "text",
          name: "phone",
          value: phone
        }),
        [phone]
      );
      useEffect(() => {
        setTimeout(() => {
          setPhone("9898098909");
        }, 3000);
      }, []);
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
        </div>
      );
    });
    
    const Parent = () => {
      const appRef = useRef(null);
      const handleClick = () => {
        console.log(appRef.current.value);
      };
      return (
        <>
          <App ref={appRef} />
          <button onClick={handleClick}>Click</button>
        </>
      );
    };
    const rootElement = document.getElementById("root");
    ReactDOM.render(<Parent />, rootElement);
    

    Working demo

    【讨论】:

    • 我的组件有来自其父组件的 forwardRef。正如你一样,我已将 ref 传递给 useImperativeHandle。
    【解决方案2】:

    如果您比较懒惰和/或优化在您的应用程序中还不是很重要,您可以将 [{}] 的依赖项传递给 useImperativeHandle() 以在每次组件重新渲染时更新,确保这些值是始终保持最新状态。

    const App = forwardRef((props, ref) => {
      const [phone, setPhone] = useState("");
      useImperativeHandle(
        ref,
        () => ({
          type: "text",
          name: "phone",
          value: phone,
          // other values that you don't have to keep track of via dependency list
        }),
        [{}]
      );
    

    【讨论】:

    • 或者,根本不提供任何依赖项,它会做同样的事情,但不会创建 2 个未使用的空值,例如useImperativeHandle(ref, () =&gt; { ... });
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    相关资源
    最近更新 更多