Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用布局页面或每页多个组件的React路由器_Reactjs_React Router - Fatal编程技术网

Reactjs 使用布局页面或每页多个组件的React路由器

Reactjs 使用布局页面或每页多个组件的React路由器,reactjs,react-router,Reactjs,React Router,我正在将react router添加到现有项目中 目前,一个模型被传递到一个根组件,该根组件包含一个用于子导航的导航组件和一个主组件 我发现的react路由器示例只有一个子组件,在不重复两个布局代码的情况下更改多个子组件的最佳方法是什么?如果我理解正确,要实现这一点,您可以在路由中定义多个组件。您可以像这样使用它: //如果您有可插拔的路由器,请在路由器的上下文之外考虑它 //在“render”的部分中,可以这样做 ,应该对你有更多帮助 编辑: 根据@Luiz的评论: 在最新版本的路由器(v3)

我正在将react router添加到现有项目中

目前,一个模型被传递到一个根组件,该根组件包含一个用于子导航的导航组件和一个主组件


我发现的react路由器示例只有一个子组件,在不重复两个布局代码的情况下更改多个子组件的最佳方法是什么?

如果我理解正确,要实现这一点,您可以在
路由中定义多个组件。您可以像这样使用它:

//如果您有可插拔的路由器,请在路由器的上下文之外考虑它
//在“render”的部分中,可以这样做
,应该对你有更多帮助

编辑: 根据@Luiz的评论:


在最新版本的路由器(v3)中,组件位于props对象的根目录中

因此:

const{main,sidebar}=this.props.children;
变成:

const{main,sidebar}=this.props;

编辑: 在react路由器v4中,这可以通过以下方式实现(根据中提供的示例):

从“React”导入React
进口{
BrowserRouter作为路由器,
路线,,
链接
}从“反应路由器dom”
//每个逻辑“路由”有两个组件,一个用于
//侧边栏和一个用于主区域。我们想
//当
//路径与当前URL匹配。
常数路由=[
{路径:'/',
确切地说:是的,
侧边栏:()=>主页!,
main:()=>主页
},
{路径:'/bubblegum',
边栏:()=>泡泡糖!,
main:()=>泡泡糖
},
{路径:'/shoelaces',
侧边栏:()=>鞋带!,
主打:()=>鞋带
}
]
常量SidebarExample=()=>(
  • 泡泡糖
  • 鞋带
{routes.map((路由,索引)=>( //可以在尽可能多的位置渲染渲染 //在你的应用程序中显示所需内容。它将随应用程序一起呈现 //与任何其他也与URL匹配的。 //所以,一个边栏或面包屑或其他任何东西 //这需要您渲染多个对象 //在同一个URL上的多个地方什么都不是 //多个s。 ))} {routes.map((路由,索引)=>( //使用与相同的路径渲染多个 //以上,但这次是不同的组件。 ))} ) 导出默认SidebarExample

请确保在此处查看新的React Router v4文档:

该组件可以是返回JSX的函数

  <Route>
    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="Invite" component={()=>(<div><Home/><Invite/></div>)} />
    </Route>
  </Route>

()} />
2019+ 执行此操作并避免滥用重新渲染的简单而干净的方法是(在react router v5上测试,需要在react router v4上确认):

与:


{routes.map((route,i)=>
r、 精确)}path={route.subRoutes.map(r=>r.path)}>
{route.subRoutes.map((subRoute,i)=>
)}
)}

再加上塞巴斯蒂安的回答,这对我来说似乎很有效,包括未找到的路由和动态子例程。下面的示例使my
LayoutAuthenticated
LayoutAnonymous
只渲染一次,而不是在使用相同布局的管线内的每个管线更改上。还添加了
PageSettings
示例以显示此体系结构中的嵌套路由。希望这能帮助别人

(示例包括打字脚本)

const publicRoutes=[
{
键:“登录”,
路径:“/login”,
组件:PageLogin,
确切地说:是的
},
{
键:“注册”,
路径:“/signup”,
组件:PageSignup,
确切地说:是的
},
{
密钥:“忘记密码”,
路径:“/忘记密码”,
组件:PageForgotPassword,
确切地说:是的
}
];
const privaterotes=[
{
钥匙:“家”,
路径:“/”,
组件:PageHome,
确切地说:是的
},
{
键:“设置”,
路径:“/settings”,
component:PageSettings,//子路由在该组件中处理
精确:false//重要的是,PageSettings只是一个新的路由器交换机容器
}
];
//Routes.tsx
{privateRoutes.map(privateRouteProps=>(
))}
{publicRoutes.map(publicRouteProps=>(
))}
//LayoutAnonymous.tsx
从“React”导入React;
导出常量布局匿名:React.FC=props=>{
返回(
{props.children}
)
}
//LayoutAuthenticated.tsx
从“React”导入React;
从“../components/MainNavBar”导入{MainNavBar};
从“../components/MainContent”导入{MainContent};
导出常量布局验证:React.FC=props=>{
返回(
{props.children}
)
}
//PrivateRoute.tsx
从“React”导入React;
进口{
路线,,
重新使用
路由程序
}从“反应路由器dom”;
从“react redux”导入{useSelector};
接口道具扩展RouteProps{}
导出常量PrivateRoute:React.FC=props=>{
const isAuthenticated:boolean=useSelector((stores)=>stores.auth.isAuthenticated);
const{component:component,…restProps}=props;
如果(!组件)返回空值;
返回(
我被认证了(
) : (
)
}
/>
)
}
//PublicRoute.tsx
从“React”导入React;
从“react router dom”导入{Route,RouteProps,Redirect};
从“react redux”导入{useSelector};
接口道具扩展RouteProps{}
export const PublicRoute:React.FC=props=>{
常量isAuthenticated:boolean=useSelector((存储)=>stores.auth.isAuthenticated
       <Switch>
         <Route exact path={["/route1/:id/:token", "/"]}>
          <Layout1>
            <Route path="/route1/:id/:token" component={SetPassword} />
            <Route exact path="/" component={SignIn} />
          </Layout1>
        </Route>
        <Route path={["/route2"]}>
          <Layout2>
            <Route path="/route2" component={Home} />
          </Layout2>
        </Route>
      </Switch>
const routes = [
  {
    layout:Layout1,
    subRoutes:[
      {
        path:"/route1/:id/:token",
        component:SetPassword
      },
      {
        exact:true,
        path:"/",
        component:SignIn
      },
    ]
  },
  {
    layout:Layout2,
    subRoutes:[
      {
        path:"/route2",
        component:Home
      },
    ]
  }
];
      <Switch>
        {routes.map((route,i)=>
          <Route key={i} exact={route.subRoutes.some(r=>r.exact)} path={route.subRoutes.map(r=>r.path)}>
            <route.layout>
              {route.subRoutes.map((subRoute,i)=>
                <Route key={i} {...subRoute} />
              )}
            </route.layout>
          </Route>
        )}
      </Switch>
// Routes.tsx

<Router>
  <Switch>
    <Route exact path={["/", "/settings", "/settings/*"]}>
      <LayoutAuthenticated>
        <Switch>
          {privateRoutes.map(privateRouteProps => (
            <PrivateRoute {...privateRouteProps} />
          ))}
        </Switch>
      </LayoutAuthenticated>
    </Route>

    <Route exact path={["/login", "/signup", "/forgot-password"]}>
      <LayoutAnonymous>
        <Switch>
          {publicRoutes.map(publicRouteProps => (
            <PublicRoute {...publicRouteProps} />
          ))}
        </Switch>
      </LayoutAnonymous>
    </Route>

    <Route path="*">
      <LayoutAnonymous>
        <Switch>
          <Route component={PageNotFound} />
        </Switch>
      </LayoutAnonymous>
    </Route>
  </Switch>
</Router>
// LayoutAnonymous.tsx

import React from 'react';

export const LayoutAnonymous: React.FC<{}> = props => {
  return (
    <div>
      {props.children}
    </div>
  )
}

// LayoutAuthenticated.tsx

import React from 'react';
import { MainNavBar } from '../components/MainNavBar';
import { MainContent } from '../components/MainContent';

export const LayoutAuthenticated: React.FC<{}> = props => {
  return (
    <>
      <MainNavBar />
      <MainContent>
        {props.children}
      </MainContent>
    </>
  )
}


// PrivateRoute.tsx

import React from "react";
import {
  Route,
  Redirect,
  RouteProps
} from "react-router-dom";
import { useSelector } from "react-redux";

interface Props extends RouteProps {}

export const PrivateRoute: React.FC<Props> = props => {
  const isAuthenticated: boolean = useSelector<any, any>((stores) => stores.auth.isAuthenticated);

  const { component: Component, ...restProps } = props;

  if (!Component) return null;

  return (
    <Route
      {...restProps}
      render={routeRenderProps =>
        isAuthenticated ? (
          <Component {...routeRenderProps} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: routeRenderProps.location }
            }}
          />
        )
      }
    />
  )
}
// PublicRoute.tsx


import React from "react";
import { Route, RouteProps, Redirect } from "react-router-dom";
import { useSelector } from "react-redux";

interface Props extends RouteProps {}

export const PublicRoute: React.FC<Props> = props => {
  const isAuthenticated: boolean = useSelector<any, any>((stores) => stores.auth.isAuthenticated);
  const { component: Component, ...restProps } = props;

  if (!Component) return null;

  return (
    <Route
      {...restProps}
      render={routeRenderProps => (
        !isAuthenticated ? (
          <Component {...routeRenderProps} />
        ) : (
          <Redirect
            to={{
              pathname: "/",
              state: { from: routeRenderProps.location }
            }}
          />
        )
      )}
    />
  )
}

// PageSettings.tsx

import React from "react";
import { LinkContainer } from "react-router-bootstrap";
import Button from "react-bootstrap/Button";
import {
  Switch,
  useRouteMatch,
  Redirect,
  Switch
} from "react-router-dom";

import { PrivateRoute } from "../../routes/PrivateRoute";
import { PageSettingsProfile } from "./profile";
import { PageSettingsBilling } from "./billing";
import { PageSettingsAccount } from "./account";

export const PageSettings = () => {
  const { path } = useRouteMatch();

  return (
    <div>
      <h2>Settings</h2>

      <Redirect strict from={path} to={`${path}/profile`} />

      <LinkContainer to={`${path}/profile`}>
        <Button>Profile</Button>
      </LinkContainer>
      <LinkContainer to={`${path}/billing`}>
        <Button>Billing</Button>
      </LinkContainer>
      <LinkContainer to={`${path}/account`}>
        <Button>Account</Button>
      </LinkContainer>

      <Switch>
        <PrivateRoute path={`${path}/profile`} component={PageSettingsProfile} />
        <PrivateRoute path={`${path}/billing`} component={PageSettingsBilling} />
        <PrivateRoute path={`${path}/account`} component={PageSettingsAccount} />
      </Switch>
    </div>
  );
};