将一个属性/变量传递给React Router 6的加载器函数

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

Passing a prop/variable to react router 6 loader function

问题

我的路由正常工作并访问组件和加载函数。我现在尝试将变量 filmsPerPage(只定义一次)传递给 Home 组件和 loader 函数。

const App = () => {
  const filmsPerPage = 12
    
  const router = createBrowserRouter([
    {
      path: '/',
      children: [
        {
          index: true,
          element: <Home {...{filmsPerPage}} />,
          loader: () => { loaderHome(filmsPerPage) }
        },
        ................. 

Home.js:

const Home = (props) => {
  const { loaderData } = useLoaderData() 
  console.log(props.filmsPerPage) 
  .......
}
    
export default Home;
    
export function loaderHome(filmsPerPage) {
  console.log(filmsPerPage)
  return defer({
    loaderData: loadPosts(null, 1, 12, null)
  })
}

filmsPerPage 属性正确传递给 Home.js 组件,而当它传递给 loader 函数时,Home.js 中的 useLoaderData() 返回 null,这意味着尽管 loader 函数中的代码正常工作,但它没有将加载程序对象返回给组件。如果我在 App.js 中这样做,Home.js 中的 useLoaderData() 函数将获取数据,但现在 loader 函数没有这个属性:

children: [
  {
    index: true,
    element: <Home {...{filmsPerPage}} />,
    loader: loaderHome
  },

我如何将 filmsPerPage 属性传递给 loader 函数,然后将加载程序数据返回给 Home.js

英文:

My routes are working and accessing components and loader functions. I'm trying now to pass variable filmsPerPage (which is defined once) to both Home component and the loader function in

App.js:

const App = () =&gt; { 
  const filmsPerPage = 12
    
  const router = createBrowserRouter([
    {
      path: &#39;/&#39;,
      children: [
        {
          index: true,
          element: &lt;Home {...{filmsPerPage}} /&gt;,
    	  loader: () =&gt; { loaderHome(filmsPerPage) }
        },
        .................

Home.js:

const Home = (props) =&gt; {
  const { loaderData } = useLoaderData() // get loader data --&gt; null
  console.log(props.filmsPerPage) // printing out correctly: 12
  .......
}
    
export default Home;
    
export function loaderHome(filmsPerPage) {
  console.log(filmsPerPage) --&gt; printing out 12
  return defer({
    loaderData: loadPosts(null, 1, 12, null)
  })
}

The prop filmsPerPage is passing correctly to Home.js component and while it's passing to the loader function, the useLoaderData() in Home.js is returning null which means that although the code in the loader function is working properly, it's not returning a loader object to the component. If I do this in App.js, the useLoaderData() function (in Home.js) will get the data but now the loader function doesn't have the prop:

children: [
  {
    index: true,
    element: &lt;Home {...{filmsPerPage}} /&gt;,
    loader: loaderHome
  },

How could I pass the filmsPerPage prop to the loader function which will then return loader data to Home.js?

答案1

得分: 1

加载函数没有返回任何内容。也许重新格式化为更可读的格式会更明显:

{
  index: true,
  element: <Home {...{filmsPerPage}} />,
  loader: () => {
    loaderHome(filmsPerPage); // &lt;-- 没有返回值!!
  },
}

加载函数仍然应返回调用 loaderHome 的结果。

示例:

{
  index: true,
  element: <Home {...{filmsPerPage}} />,
  loader: () => {
    return loaderHome(filmsPerPage); // &lt;-- 在函数块中显式返回
  },
}
{
  index: true,
  element: <Home {...{filmsPerPage}} />,
  loader: () => loaderHome(filmsPerPage), // &lt;-- 隐式箭头函数返回
}

您甚至可以重写 loaderHome柯里化,例如,在函数作用域中封闭 filmsPerPage 参数。

export function loaderHome(filmsPerPage) {
  console.log(filmsPerPage); --> 打印出 12

  // 返回加载函数
  return (loaderArgs) => {
    return defer({
      loaderData:  loadPosts(null, 1, filmsPerPage, null);
    });
  };
}
{
  index: true,
  element: <Home {...{filmsPerPage}} />,
  loader: loaderHome(filmsPerPage),
}
英文:

The loader function isn't returning anything. Perhaps reformatted to a more readable format will make this more apparent:

{
  index: true,
  element: &lt;Home {...{filmsPerPage}} /&gt;,
  loader: () =&gt; {
    loaderHome(filmsPerPage); // &lt;-- not returned!!
  },
}

The loader should still return the result of calling loaderHome.

Examples:

{
  index: true,
  element: &lt;Home {...{filmsPerPage}} /&gt;,
  loader: () =&gt; {
    return loaderHome(filmsPerPage); // &lt;-- explicit return in function block
  },
}
{
  index: true,
  element: &lt;Home {...{filmsPerPage}} /&gt;,
  loader: () =&gt; loaderHome(filmsPerPage), // &lt;-- implicit arrow function return
}

You could even rewrite loaderHome to curry, e.g. close over in function scope, the filmsPerPage argument.

export function loaderHome(filmsPerPage) {
  console.log(filmsPerPage); --&gt; printing out 12

  // Return loader function
  return (loaderArgs) =&gt; {
    return defer({
      loaderData:  loadPosts(null, 1, filmsPerPage, null);
    });
  };
}
{
  index: true,
  element: &lt;Home {...{filmsPerPage}} /&gt;,
  loader: loaderHome(filmsPerPage),
}

huangapple
  • 本文由 发表于 2023年6月1日 22:53:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383199.html
匿名

发表评论

匿名网友

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

确定