无法在函数中使用 useState 获取第一个值

发布于 2025-01-11 13:57:49 字数 679 浏览 0 评论 0原文

我需要根据数据值显示文本。通过运行代码,我希望看到单击按钮后可以显示“Test1:1”,但我不能。有什么方法可以实现这一点吗?

以下是包含代码的示例沙箱链接。 https://codesandbox.io/s/restless-wildflower -9pl09k?file=/src/Parent.js

export default function Parent(props) {
  const [data, setData] = useState(0);
  const onClick = () => {
    setData(1);
    console.log(data);
    setData(2);
  };
  return (
    <>
      <button onClick={onClick}> Click here </button>
      {data === 1 ? <div>Test1: {data}</div> : <div>Test2: {data}</div>}
    </>
  );
}

I need to show the text according to the data value. By running the code, I want to see the 'Test1: 1' can be shown after I clicked the button, but I can't. Any method to make this happen?

Below is a sample sandbox link including the code.
https://codesandbox.io/s/restless-wildflower-9pl09k?file=/src/Parent.js

export default function Parent(props) {
  const [data, setData] = useState(0);
  const onClick = () => {
    setData(1);
    console.log(data);
    setData(2);
  };
  return (
    <>
      <button onClick={onClick}> Click here </button>
      {data === 1 ? <div>Test1: {data}</div> : <div>Test2: {data}</div>}
    </>
  );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心荒芜 2025-01-18 13:57:49

useState 返回的 setState 函数不会直接更新状态。相反,它用于发送 React 在下一次异步状态更新期间将使用的值。 console.log 是一种效果,因此如果您想查看每次更改时记录的data,您可以使用 React.useEffect运行下面的代码并单击0按钮几次以查看浏览器中的状态变化和效果。

function App() {
  const [data, setData] = React.useState(0)
  React.useEffect(_ => console.log("data", data), [data])
  return <button
    onClick={_ => setData(data + 1)}
    children={data}
  />
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

您的评论讨论了网络请求示例。可以设计自定义挂钩来适应复杂的用例并使您的组件易于编写。

function App() {
  const [{fetching, error, data}, retry] = useAsync(_ => {
    return fetch("https://random-data-api.com/api/users/random_user")
      .then(res => res.json())
  }, [])
  if (fetching) return <pre>Loading...</pre>
  if (error) return <pre>Error: {error.message}</pre>
  return <div>
    <button onClick={retry} children="retry" />
    <pre>{JSON.stringify(data, null, 2)}</pre>
  </div>
}

function useAsync(f, deps) {
  const [state, setState] = React.useState({fetching: true})
  const [ts, setTs] = React.useState(Date.now())
  React.useEffect(_ => {
    f()
      .then(data => setState({fetching: false, data}))
      .catch(error => setState({fetching: false, error}))
  }, [...deps, ts])
  return [
    state,
    _ => {
      setState({fetching: true, error: null, data: null})
      setTs(Date.now())
    }
  ]
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

The setState function returned by useState does not directly update the state. Instead it is used to send the value that React will use during the next asynchronous state update. console.log is an effect so if you want to see data logged every time it is changed, you can use React.useEffect. Run the code below and click the 0 button several times to see the state changes and effects in your browser.

function App() {
  const [data, setData] = React.useState(0)
  React.useEffect(_ => console.log("data", data), [data])
  return <button
    onClick={_ => setData(data + 1)}
    children={data}
  />
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

Your comment talks about a network request example. Custom hooks can be designed to accommodate complex use cases and keep your components easy to write.

function App() {
  const [{fetching, error, data}, retry] = useAsync(_ => {
    return fetch("https://random-data-api.com/api/users/random_user")
      .then(res => res.json())
  }, [])
  if (fetching) return <pre>Loading...</pre>
  if (error) return <pre>Error: {error.message}</pre>
  return <div>
    <button onClick={retry} children="retry" />
    <pre>{JSON.stringify(data, null, 2)}</pre>
  </div>
}

function useAsync(f, deps) {
  const [state, setState] = React.useState({fetching: true})
  const [ts, setTs] = React.useState(Date.now())
  React.useEffect(_ => {
    f()
      .then(data => setState({fetching: false, data}))
      .catch(error => setState({fetching: false, error}))
  }, [...deps, ts])
  return [
    state,
    _ => {
      setState({fetching: true, error: null, data: null})
      setTs(Date.now())
    }
  ]
}

ReactDOM.render(<App/>, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

习惯成性 2025-01-18 13:57:49

console.log(data) 没有反映最新数据的原因是 React 管理状态。对 setState() 的调用是异步的,如果您想依赖状态的新值,正确的方法是传递旧状态的函数,返回当前状态。 参考。文档

The reason the console.log(data) did not reflect the latest data is because of the React manages state. Calls to setState() are asynchronous, and if you want to rely on the new value of the state, the correct way is to pass a function of old state, returning the current state. ref. documentation

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文