`useEffect`中的`location.state`在组件的初始渲染时未被触发。

huangapple go评论74阅读模式
英文:

`location.state` in dependency of `useEffect` not getting triggered for the initial rendering of component

问题

我有一个父组件,其中包含对子路由的 Outlet

我想从父组件 (App.js) 将数据传递给由 Outlet 渲染的默认链接 (Test.js)。

为此,我使用了位置对象的状态,并将数据从父组件传递过去。

<Link to="" state={{ data }}>
  渲染测试
</Link>

尽管在初始渲染时,在子组件 (Test.js) 中它仍然是空的,但如果我导航到父组件中的其他路由(路由:/dummy,组件:Dummy.js)然后返回到 Test.js 组件的路由,我可以在 location.state 中看到值。

用于更清晰理解的 Codesandbox 链接: https://codesandbox.io/s/location-state-zjs5rt

我尝试在 useEffect 中添加 location.state 作为依赖,但它在初始渲染时没有被触发。

useEffect(() => {
  if (location.state) {
    setTestData(location.state.data);
  }
}, [location?.state]);

我想从 App.js 传递一些异步数据,并在 Test.js 组件中使用它来渲染特定的内容,我应该如何实现这一点?

英文:

I have a parent component which is having Outlet for sub routes.

I wanted to pass the data from the parent component (App.js) to the component rendered by Outlet for the default Link (Test.js).

For which, I used the state object of location and passed the data from parent Component.

&lt;Link to=&quot;&quot; state={{ data }}&gt;
  Render test
&lt;/Link&gt;

Although on initial render, it is still null in child component (Test.js), but if I navigate to some other route (route: /dummy, component : Dummy.js) within that parent and come back to Test.js components route, I am able to see value in the location.state.

Codesandbox link for more clarity: https://codesandbox.io/s/location-state-zjs5rt

I tried adding location.state as dependency in useEffect but it is not getting triggered on the initial render.

useEffect(() =&gt; {
  if (location.state) {
    setTestData(location.state.data);
  }
}, [location?.state]);

I wanted to pass some async data from App.js and use it inside Test.js component to render certain things, how can I achieve this?

答案1

得分: 1

如果你只想在App组件中向任何嵌套路由的element组件提供一些状态,那么我建议通过React上下文通过Outlet组件进行传递。路由组件使用useOutletContext钩子来访问上下文。

示例:

App

import { Outlet, Link } from "react-router-dom";
import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState(null);

  useEffect(() => {
    setTimeout(() => {
      setData("稍后获取的数据");
    }, 2000);
  }, []);

  return (
    <div className="App">
      {data ? (
        <>
          <h2>这是APP组件</h2>
          <ul>
            <li>
              <Link to="/">渲染测试</Link>
            </li>
            <li>
              <Link to="/dummy">另一个虚拟组件</Link>
            </li>
          </ul>
          <Outlet context={{ data }} /> // <-- 通过上下文传递
        </>
      ) : (
        <>加载中...</>
      )}
    </div>
  );
}

Test

import { useEffect } from "react";
import { useOutletContext } from "react-router-dom";

export default function Test(props) {
  const { data } = useOutletContext();

  useEffect(() => {
    console.log("使用上下文的数据", data);
  }, [data]);

  return <div>这是另一个组件 "{data}"</div>;
}

`useEffect`中的`location.state`在组件的初始渲染时未被触发。

英文:

If you are just wanting to make available some state in the App component to any of the nested route's element components then I'd suggest passing it via the React context available via the Outlet component. The routed components use the useOutletContext hook to access the context.

Example:

App

import { Outlet, Link } from &quot;react-router-dom&quot;;
import { useEffect, useState } from &quot;react&quot;;

export default function App() {
  const [data, setData] = useState(null);

  useEffect(() =&gt; {
    setTimeout(() =&gt; {
      setData(&quot;data that comes later&quot;);
    }, 2000);
  }, []);

  return (
    &lt;div className=&quot;App&quot;&gt;
      {data ? (
        &lt;&gt;
          &lt;h2&gt;This is APP component&lt;/h2&gt;
          &lt;ul&gt;
            &lt;li&gt;
              &lt;Link to=&quot;/&quot;&gt;Render test&lt;/Link&gt;
            &lt;/li&gt;
            &lt;li&gt;
              &lt;Link to=&quot;/dummy&quot;&gt;Another dummy component&lt;/Link&gt;
            &lt;/li&gt;
          &lt;/ul&gt;
          &lt;Outlet context={{ data }} /&gt; // &lt;-- passed in context
        &lt;/&gt;
      ) : (
        &lt;&gt;Loading...&lt;/&gt;
      )}
    &lt;/div&gt;
  );
}

Test

import { useEffect } from &quot;react&quot;;
import { useOutletContext } from &quot;react-router-dom&quot;;

export default function Test(props) {
  const { data } = useOutletContext();

  useEffect(() =&gt; {
    console.log(&quot;data using location&quot;, data);
  }, [data]);

  return &lt;div&gt;This is another component &quot;{data}&quot;&lt;/div&gt;;
}

`useEffect`中的`location.state`在组件的初始渲染时未被触发。

huangapple
  • 本文由 发表于 2023年1月9日 06:55:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051874.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定