简体   繁体   English

使用 react 钩子重用数据

[英]Reuse data with react hooks

I need to reuse data in my app with hook, so I created a hook called useData我需要用钩子重用我的应用程序中的数据,所以我创建了一个名为useData的钩子

import { useState } from "react";

export default function useData() {
  const [message, setMessage] = useState("");
  const [type, setType] = useState("error");

  return [{ message, type }, { setMessage, setType }];
}

And then I use my hook in my app like below.然后我在我的应用程序中使用我的钩子,如下所示。

function App() {
  const [data, action] = useData();

  const handleClick = () => {
    action.setMessage("Hello message");
    action.setType("info");

    alert(JSON.stringify(data));
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button className="btn" onClick={handleClick}>
        Alert Data
      </button>
    </div>
  );
}

When I clicked the button Alert Data at the first time it will alert当我第一次单击按钮Alert Data时,它会发出警报

{message: "", type: "error"}

My expectation is我的期望是

{message: "Hello message", type: "info"}

What am I doing it wrong here?我在这里做错了什么? Please let me know, and is there any way to fix this code?请让我知道,有没有办法修复此代码?

Here's the codesandbox code: https://codesandbox.io/embed/romantic-hugle-zm2e2?fontsize=14&hidenavigation=1&theme=dark这是代码和框代码: https ://codesandbox.io/embed/romantic-hugle-zm2e2 ? fontsize =14& hidenavigation =1& theme = dark

Thanks for your attention.感谢您的关注。

You're counting on data being updated the instant you call your onClick handler, but that won't be true until the next render.您指望在调用onClick处理程序时立即更新data ,但直到下一次渲染才会如此。 Instead, consider using a useEffect hook.相反,请考虑使用useEffect钩子。 In the following example, I've also created a stateful open variable to tell the modal when to be open.在下面的示例中,我还创建了一个有状态的open变量来告诉模态何时打开。

function App() {
  const [data, action] = useData();
  const [open, setOpen] = useState(false);

  const handleClick = () => {
    action.setMessage("Hello message");
    action.setType("info");
    setOpen(true);
  };

  useEffect(() => {
    if (open) {
      alert(JSON.stringify(data));
      setOpen(false);
    }
  }, [open, data])

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button className="btn" onClick={handleClick}>
        Alert Data
      </button>
    </div>
  );
}

In React.js, setState isn't a synchronous function.在 React.js 中, setState 不是同步函数。 That is, setState doesn't change the state instantly.也就是说, setState 不会立即更改状态。 For this case, setState has a version with the completion callback.对于这种情况, setState 有一个带有完成回调的版本。 You can define a custom Hook with the completion callback.您可以使用完成回调定义自定义 Hook。 Fortunately, there is an npm package called "use-state-with-callback".幸运的是,有一个名为“use-state-with-callback”的 npm 包。

Or you can write the code as follows.或者您可以编写如下代码。

useData.js使用Data.js

 export default function useData(msg, cb) { const [message, setMessage] = useState(msg); useEffect(() => cb(message), [message]); return [message, setMessage]; }

index.js索引.js

 function App() { const callback = (msg) => { alert(JSON.stringify(msg)); } const [message, setMessage] = useData({ content: "", type: "error" }, callback); const handleClick = () => { setMessage({ content: "Hello message", type: "info" }); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> <button className="btn" onClick={handleClick}> Alert Data </button> </div> ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);

This works fine.这工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM