在 Reactjs 中实现嵌套路由的问题

Posted

技术标签:

【中文标题】在 Reactjs 中实现嵌套路由的问题【英文标题】:Problem In Implementing Nested Routing In Reactjs 【发布时间】:2020-07-09 04:23:07 【问题描述】:

我知道有太多类似的问题,我试过了,但没有一个能解决我的问题。我的路线结构如下:

Layout
  /Settings Route
     UserSettings [Container]
        UserSettings [Component]
  /Private Route x
  /Private Route y
  /Private Route z
  /Private Route a

我有一个包含所有私人路线的布局。其中一条路线是设置路线。 我希望我的设置路由看起来像 facebooks 设置页面,即有一个带有不同链接的侧边栏,这些链接作为设置的子路由打开,例如:

localhost:3000/settings/**settings1**
localhost:3000/settings/**settings2**
localhost:3000/settings/**settings3**
localhost:3000/settings/**settings4**

其中 settings1-2-3-4 是一个子路由,并且会发生变化。 我尝试将侧边栏和链接与 NavLinks 放在 UserSettings [组件]

<Route path=`$path/:id` component=UserSettings[Component] />

链接,点击后会转到指定的网址,即localhost:3000/settings/profile,但页面只是空白。

注意:链接和侧边栏显示在 localhost:3000/settings/

但它不起作用。请告诉我怎么做,我已经尝试了所有的方法。

我的代码:

//Layout.js


 //secured routes
      const PrivateRoutes = ( component, path, isUserLogged ) => 
          return isUserLogged ? (
              <Route
                  exact
                  path=path
                  render=() => <Suspense fallback=<Spinner />>component</Suspense>
              />
          ) : (
              <Redirect exact to="/auth" />
          );
      ;

        <Switch>
            <PrivateRoutes
                path="/user"
                component=<UserProfiles />
                isUserLogged=this.props.isUserLogged
            />
            <PrivateRoutes
                path="/settings/"
                component=<UserSettings />
                isUserLogged=this.props.isUserLogged
            />

            <PrivateRoutes
                path="/"
                component=<Posts showMoreOptions=this.showPopupOptionsHandler />
                isUserLogged=this.props.isUserLogged
            />
        </Switch>

//UserSettings.js[组件]

const EditProfileBasicInfo = (props) => 
    const [files, setFiles] = useState([]);

    return (
        <div className=style.userData>
            <h3>Your Details</h3>

            <FilePond
                className=style.Filepond
                allowMultiple=false
                onupdatefiles=(fileItems) => 
                    setFiles( files: fileItems.map((fileItem) => fileItem.file) );
                
                imagePreviewHeight=50
                imageCropAspectRatio="1:1"
                // imageResizeTargetWidth=200
                imageResizeTargetHeight=100
                stylePanelLayout="compact circle"
                styleLoadIndicatorPosition="top center"
                // styleButtonRemoveItemPosition="center bottom"
                maxFiles=1
                allowImagePreview=true
                server="./"
            />

            <form onSubmit=props.submit>
                <div className=style.Inline>
                    <input
                        type="text"
                        placeholder="First Name"
                        id="firstName"
                        value=props.info.firstName
                        onChange=(event) => props.changed(event)
                    />
                    <input
                        type="text"
                        id="lastName"
                        placeholder="Last Name"
                        value=props.info.lastName
                        onChange=(event) => props.changed(event)
                    />
                </div>

                <textarea
                    placeholder="Bio"
                    rows="4"
                    id="bio"
                    value=props.info.bio
                    onChange=(event) => props.changed(event)
                />

                <input
                    type="Email"
                    id="email"
                    placeholder="Email"
                    value=props.info.email
                    disabled
                />

                <button onClick=props.submit>Save</button>
            </form>
        </div>
    );
;

const SidebarLinks = ( url, to, name ) => 
    return (
        <NavLink exact to=`$url$to`>
            <li>
                <button>name</button>
            </li>
        </NavLink>
    );
;

const UserData = (props) => 
    console.log(props);
    const currentUrl = props.match.url;
    return (
        <Grid container direction="row" className=style.UserData_MainWrapper>
            <Grid item xs=2>
                <ul className=style.OptionButtons>
                    <SidebarLinks to="profile" name="Profile" url=currentUrl />
                    <SidebarLinks to="privacy" name="Privacy" url=currentUrl />
                    <SidebarLinks to="security" name="Security" />
                    <SidebarLinks to="logout" name="Logout" />
                </ul>
            </Grid>

            <Grid xs=10 item>
                <Route
                    to=`$props.match.url/:settingType`
                    render=() => <EditProfileBasicInfo ...props />
                />
            </Grid>
        </Grid>
    );
;

// UserSettings.js [Container] --> UserData 基本上就是 UserSettings 组件 // 我稍后重命名它。

const info = 
            email: emailVal,
            firstName: firstName,
            lastName: lastName,
            bio: bio,
        

        return (
            <div className=style.CompleteUserData_MainWrapper>
                <UserData
                    submit=this.onSubmitHandler
                    info=info
                    changed=this.onChangeHandeler
                />
            </div>
        )

【问题讨论】:

嗨,欢迎来到 ***。感谢您提供有关您的路线结构和问题的详细信息,但如果没有 Minimal, Complete, and Reproducible 代码示例,则无法提供太多建议或帮助。您能否更新您的问题以包括路由器组件和您的UserSettings 组件? react-router-dom 有一些微妙之处需要了解。 抱歉,已添加代码! 【参考方案1】:

我通过从设置私人​​路线中删除确切的道具来修复它

    //Layout.js


 //secured routes
      const PrivateRoutes = ( component, path, isUserLogged ) => 
          return isUserLogged ? (
              <Route
                 // exact   ---> This one. It stopped my routes from being displayed
                  path=path
                  render=() => <Suspense fallback=<Spinner />>component</Suspense>
              />
          ) : (
              <Redirect exact to="/auth" />
          );
      ;

---

And changing the below code:

    const SidebarLinks = ( url, to, name ) => 
    return (
        <NavLink exact to=`$url$to`>
            <li>
                <button>name</button>
            </li>
        </NavLink>
    );
;

const UserData = (props) => 
    console.log(props);
    const path, url = useRouteMatch(); ----> //import use route match
    return (
        <Grid container direction="row" className=style.UserData_MainWrapper>
            <Grid item xs=2>
                <ul className=style.OptionButtons>
                    <SidebarLinks to="/profile" name="Profile" url=url />  //Here
                    <SidebarLinks to="/privacy" name="Privacy" url=url />  //Here
                    <SidebarLinks to="/security" name="Security" />
                    <SidebarLinks to="/logout" name="Logout" />
                </ul>
            </Grid>

            <Grid xs=10 item>
               <Switch>
               <Route path=path exact />
                <Route
                    to=`$path/profile`
                    render=() => <EditProfileBasicInfo ...props />
                /> 
              </Switch>
            </Grid>

【讨论】:

以上是关于在 Reactjs 中实现嵌套路由的问题的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS:组件未在嵌套路由中呈现

尝试在 Reactjs 中实现一个简单的承诺

如何在 React 中实现分页

在reactjs功能组件中实现contextType的正确方法是什么?

在 React-Router-Dom 中声明嵌套路由的方式

在 React Js 中实现 Quickblox 视频会议时获取“DTLS 警报”