我有一台路由:

const router = createBrowserRouter(
  [
    {
      path: '/',
      element: <Navigate to={'/dashboards'}/>
    },
    {
      path: '/dashboards',
      element: <Dashboards/>,
      loader: () => store.dispatch(retrieveWarehouses()),
      children: [
        {
          path: ':warehouse',
          element: <Dashboard/>,
          loader: ({ params }) => store.dispatch(monitorWarehouse(params.warehouse))
        }
      ]
    }
  ]
)

按原样定义,不呈现<Dashboard/>组件,仅呈现其父仪表板列表(Dashboards,请注意复数).然而,仍然触发子Dashboard的加载器.

如果我不使用嵌套路由:

const router = createBrowserRouter(
  [
    {
      path: '/',
      element: <Navigate to={'/dashboards'}/>
    },
    {
      path: '/dashboards',
      element: <Dashboards/>,
      loader: () => store.dispatch(retrieveWarehouses()),
    },
    {
      path: '/dashboards/:warehouse',
      element: <Dashboard/>,
      loader: ({ params }) => store.dispatch(monitorWarehouse(params.warehouse))
    }
  ]
)

子组件Dashboard被正确地呈现,但是父组件的加载器不被触发.

Here are the components:

Dashboards

const Dashboards: React.FC<any> = () => {
  const {
    warehouses,
    loading
  } = useAppSelector(selectWarehouseListState)

  if (loading) {
    return (
      <div className={'warehouse-list'}>
        <h1>Select warehouse</h1>
        <Spinner/>
      </div>
    )
  }

  return (
    <div className={'warehouse-list'}>
      <h1>Select warehouse</h1>
      {
        warehouses.map((wh: Warehouse) => (
          <NavLink to={`/dashboards/${wh.name}`} key={wh.name}>
            <div className={'selectable-warehouse container'}>
              {wh.name}
            </div>
          </NavLink>
        ))
      }
    </div>
  )
}

Dashboard

const Dashboard: React.FC<any> = () => {
  const { loading } = useAppSelector(selectWarehouseState)
  const { warehouse } = useParams()
  const dispatch = useAppDispatch()

  useEffect(() => {
    return () => {
      dispatch(stopMonitorWarehouse(warehouse))
    }
  }, [dispatch])

  if (loading) {
    return (
      <div className={'dashboard loading shrinkable'}>
        <div className={'header'}>
          <NavLink to={'/dashboards'} className={'nav-back'}>
            <ArrowBack/>
          </NavLink>
          <div className={'selected-warehouse-name'}>{warehouse}</div>
        </div>
        <div className={'status connecting'}>status: connecting</div>
        <Spinner/>
      </div>
    )
  }

  return (
    <div className={'dashboard active shrinkable'}>
      <div className={'header'}>
        <NavLink to={'/dashboards'} className={'nav-back'}>
          <ArrowBack/>
        </NavLink>
        <div className={'selected-warehouse-name'}>{warehouse}</div>
      </div>
      <div className={'status connected'}>status: connected</div>
      <div className={'logs-metrics'}>
        <Logs/>
      </div>
    </div>
  )
}

如何访问/dashboards/foo并同时触发两个加载器?

推荐答案

如果将Dashboards组件呈现为布局路由,则它必须呈现Outlet,以便其嵌套的路由将其内容呈现到其中.

示例:

import { Outlet } from 'react-router-dom';

const Dashboards: React.FC<any> = () => {
  const {
    warehouses,
    loading
  } = useAppSelector(selectWarehouseListState)

  return (
    <div className={'warehouse-list'}>
      <h1>Select warehouse</h1>
      {loading ? (
        <Spinner />
      ) : (
        <>
          {warehouses.map((wh: Warehouse) => (
            <NavLink to={`/dashboards/${wh.name}`} key={wh.name}>
              <div className={'selectable-warehouse container'}>
                {wh.name}
              </div>
            </NavLink>
          ))}
          <Outlet />
        </>
      )}
    </div>
  );
};

但是,在我的用例中,我不希望同时呈现这两个组件, 后者应该优先于另一个.

如果我理解这一部分,您希望DashboardsDashboard组件独立呈现,但Dashboards‘S加载器函数仍然在嵌套路径上被调用even while.为此,您将呈现Dashboards作为嵌套索引路径,其中加载器函数位于父布局路径上.

示例:

const router = createBrowserRouter(
  [
    {
      path: '/',
      element: <Navigate to="/dashboards" />
    },
    {
      path: '/dashboards',
      loader: () => store.dispatch(retrieveWarehouses()),
      children: [
        {
          index: true,
          element: <Dashboards />,
        },
        {
          path: ':warehouse',
          element: <Dashboard />,
          loader: ({ params }) => {
            store.dispatch(monitorWarehouse(params.warehouse));
          },
        }
      ]
    }
  ]
);

如果未指定element,则默认情况下,"/dashboards"路由将呈现Outlet,而当父路由匹配时,将呈现Dashboards组件.不需要更改Dashboards组件.

Reactjs相关问答推荐

全局上下文挂钩-替代不起作用

如何使用react-router-dom导航到网页中的其他路由?

NextJS(AppRouter)、Apollo(客户端),在根布局中使用ApolloProvider时出错

useCallback()是否应该用于作为prop传递给子组件的函数,即使该组件包装在memo()中?

React Router:在没有手动页面刷新的情况下,路由不会更新内容

是否为Reaction中未使用的组件生成Tailwincss样式?

未定义发送的数据无法在reactjs中找到原因

我在Route组件上使用元素属性,这样就不需要ID了吗?

如何在我的 React 应用程序中仅显示我的 Register 组件

在 React 中是否有任何理由要记住 Redux 操作创建者?

如果我使用 formik,如何在嵌套对象中写入正确的值?

基于 React/NextJS Timer 的文本淡入/淡出不起作用

将 clerk 与 supabase 集成的最佳实践

使用 react-markdown 组件时 Tailwind CSS 的问题

从其他组件切换 FieldSet

调用 Statsig.updateUser 时 UI 不呈现

当状态改变时如何执行一些动作,但只针对第一次更新?

我在使用 Elements of stripe 时使用 React router v6

您无权使用阻止 webRequest 侦听器.请务必在 list 中声明 webRequestBlocking 权限

根据计算 ReactJs 更新输入字段