javascript - 更改路线时状态正在重置
问题描述
我的反应应用程序中有一个Navbar
组件。我管理组件内的管理状态Navbar
。当我已经在Lag
路线上并尝试路由到Medlemar
导航栏的管理部分时,它就会消失。这是因为更改路由时管理员状态正在重置。我怎样才能防止这种情况?
导航栏组件:
function Navbar({ data }) {
const [user, setUser] = useState(null)
const [admin, setAdmin] = useState(false)
const [passedData, setData] = useState(undefined)
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
setUser(user)
})
if (passedData) {
console.log(passedData)
} else {
setData(data)
}
if (user) {
if(passedData !== undefined) {
firebase.firestore().collection('teams').doc(passedData.teamID).collection('members').doc(user.uid).get().then((snapshot) => {
const administrator = snapshot.get('role')
if (administrator === 'admin') {
setAdmin(true)
} else {
setAdmin(false)
}
})
}
}
}, [user])
return (
<nav className='navbar'>
<ul className='nav-menu-items'>
<li className="nav-text">
<Link to="/">
<AiIcons.AiFillDashboard size="1.4em" className="icon" />
<span>Dashboard</span>
</Link>
</li>
<li className="nav-text">
<Link to="/lag">
<AiIcons.AiOutlineTeam size="1.4em" className="icon" />
<span>Lag</span>
</Link>
</li>
<li className="nav-text">
<Link to="/profil">
<BsIcons.BsPerson size="1.4em" className="icon" />
<span>Profil</span>
</Link>
</li>
<li className="nav-text">
<Link to="/betaling">
<GiIcons.GiPayMoney size="1.4em" className="icon" />
<span>Betaling</span>
</Link>
</li>
</ul>
{admin ?
<>
<span className="admin-text">Admin</span>
<div className="navbar-divider"></div>
<ul className="nav-menu-items">
<li className="nav-text">
<Link to={{
pathname: `/lag/${data.teamID}/admin/medlemar`,
state: {
passedData: data,
}
}}>
<BsIcons.BsPeopleFill className="icon" size="1.4em" />
<span>Medlemar</span>
</Link>
</li>
</ul>
</>
:
null
}
</nav>
)
}
应用程序.js
function App() {
return (
<>
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/logg-inn" component={Login} />
<Route path="/lag/:id" exact component={Team} />
<Route path="/profil" component={Profile} />
<Route path="/registrer-deg" component={Signup} />
<Route path="/lag" exact component={Teams} />
<Route path="/lag/:id/innstillingar" exact component={TeamSettings} />
<Route path="/lag/:id/betaling" exact component={Payment} />
<Route path="/lag/:id/arrangement" exact component={Events} />
<Route path="/lag/:id/admin/medlemar" component={Members} />
</Switch>
</Router>
</>
);
}
解决方案
如果您想使用导航栏在路由之间保持状态,那么您应该将其用作包装器组件并用它包装 /lag 路由。
一般来说,最好使用 React Context 或任何其他状态管理库来避免将来出现问题,但我提供的解决方案应该可以工作。
您的 Navbar 组件可以带子项(用于包装目的),并且看起来像这样:
function Navbar({ data, children }) {
const [user, setUser] = useState(null);
const [admin, setAdmin] = useState(false);
const [passedData, setData] = useState(undefined);
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
setUser(user);
});
if (passedData) {
console.log(passedData);
} else {
setData(data);
}
if (user) {
if (passedData !== undefined) {
firebase
.firestore()
.collection('teams')
.doc(passedData.teamID)
.collection('members')
.doc(user.uid)
.get()
.then((snapshot) => {
const administrator = snapshot.get('role');
if (administrator === 'admin') {
setAdmin(true);
} else {
setAdmin(false);
}
});
}
}
}, [user]);
return (
<nav className="navbar">
<ul className="nav-menu-items">
<li className="nav-text">
<Link to="/">
<AiIcons.AiFillDashboard
size="1.4em"
className="icon"
/>
<span>Dashboard</span>
</Link>
</li>
<li className="nav-text">
<Link to="/lag">
<AiIcons.AiOutlineTeam size="1.4em" className="icon" />
<span>Lag</span>
</Link>
</li>
<li className="nav-text">
<Link to="/profil">
<BsIcons.BsPerson size="1.4em" className="icon" />
<span>Profil</span>
</Link>
</li>
<li className="nav-text">
<Link to="/betaling">
<GiIcons.GiPayMoney size="1.4em" className="icon" />
<span>Betaling</span>
</Link>
</li>
</ul>
{admin ? (
<>
<span className="admin-text">Admin</span>
<div className="navbar-divider"></div>
<ul className="nav-menu-items">
<li className="nav-text">
<Link
to={{
pathname: `/lag/${data.teamID}/admin/medlemar`,
state: {
passedData: data,
},
}}
>
<BsIcons.BsPeopleFill
className="icon"
size="1.4em"
/>
<span>Medlemar</span>
</Link>
</li>
</ul>
</>
) : null}
{children}
</nav>
);
}
然后您的应用程序将看起来像这样:
function App() {
return (
<>
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/logg-inn" component={Login} />
<Route path="/lag/:id" exact component={Team} />
<Route path="/profil" component={Profile} />
<Route path="/registrer-deg" component={Signup} />
<Navbar>
<Route path="/lag" exact component={Teams} />
<Route path="/lag/:id/innstillingar" exact component={TeamSettings} />
<Route path="/lag/:id/betaling" exact component={Payment} />
<Route path="/lag/:id/arrangement" exact component={Events} />
<Route path="/lag/:id/admin/medlemar" component={Members} />
</Navbar>
</Switch>
</Router>
</>
);
}
推荐阅读
- typescript - 在 postInstall 脚本上对子模块使用 global.d.ts
- python - 无法加载 Colaboratory
- java - java.sql.Types.JSON 不是默认的 JDBC 类型
- python - 相交数取决于相交数据帧的顺序
- javascript - 为什么我得到 val.slice is not a function
- css - 为什么我的从 HTML 文件简单链接的样式表不适用?
- r - 如何查找预定义绘图主题的设置(例如 ggplot、yarrr)
- android - 尽管更改了 gradle 插件,但新创建的 kotlin 项目给出了 gradle 错误
- python - 使用 Django API 处理并发请求
- java - 如何使用java在appium测试中访问移动浏览器的本地存储?