reactjs - 在 Reactjs 中实现嵌套路由的问题
问题描述
我知道有太多类似的问题,我试过了,但没有一个能解决我的问题。我的路线结构如下:
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]} />
当点击链接时,会转到指定的 url,即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>
)
解决方案
我通过从设置 Private Route 中删除确切的道具来修复它
//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>
推荐阅读
- linux - rsyslog 不打开 tcp 监听器
- visual-studio-2019 - Windows Defender 将默认 Visual Studio 2019 Windows 桌面应用程序模板的 .exe 识别为恶意
- clojure - 自动评估依赖文件(缓冲区)
- visual-studio-code - 如何在 VSCode 扩展中创建浮动窗口?
- asp.net - 如何将整个网站输出为“静态”文件(即 html、css、img)
- r - 带有 R 的 Excel 数据透视表(添加总数和百分比)而不是计数 - 包括 MRE
- mysql - 将mysql中的多条记录更新为单个查询
- instagram - Instagram API 按位置地理标签获取帖子
- r - R:替换所有不等于一组值的值
- arrays - 如何在 javaScript 中迭代这个 json 文件?