404自定义页面无法使用useContext和React Router



如果我输入的URL在我的应用程序中不存在,它会将我发送到一个自定义的404未找到页面。但是,当我用<User.Provider value={value}> .... </User.Provider>包装导航栏时,404未找到组件会出现在所有页面上。

基本上,我不希望NoMatch组件出现在所有其他页面上,只有当url不存在/与我的应用程序的导航栏不匹配时。

因此,如果我键入localhost:5000/this-does-not-exist-12345212wergdv它应该会把我带到自定义组件NoMatch

代码沙箱链接。https://codesandbox.io/s/delicate-sea-b2r96?file=/src/App.js

有人知道我该怎么解决吗?谢谢你的帮助。下面是我的代码。

UserContext.jsx代码

import React from "react";
export const User = React.createContext(null);

Home.jsx代码

import React from "react";
import {User} from "../auth/UserContext";
const Home = props => {

const {user} = React.useContext(User);

return (

<div>
<h4>This is Home page</h4>
<h4>User: {JSON.stringify({user})}</h4>
</div>
);
}
export default Home;

Navbar.jsx代码

import React from "react";
import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect,
useLocation,
useHistory
} from "react-router-dom";
import {User} from "../auth/UserContext";
import Home from "../pages/Home";
const Navbar = React.memo(props => {

const [user, setUser] = React.useState(null);
const value = React.useMemo(() => ({user, setUser}), [user, setUser]);
const history = useHistory();

return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/old-match">Old Match, to be redirected</Link>
</li>
<li>
<Link to="/will-match">Will Match</Link>
</li>
<li>
<Link to="/will-not-match">Will Not Match</Link>
</li>
<li>
<Link to="/also/will/not/match">Also Will Not Match</Link>
</li>
</ul>
<Switch>
<User.Provider value = {value}>
<Route exact path="/">
<Home />
</Route>
<Route path="/old-match">
<Redirect to="/will-match" />
</Route>
<Route path="/will-match">
<WillMatch />
</Route>

<Route path="*">
<NoMatch />
</Route>
</User.Provider>

</Switch>
</div>
</Router>
);
})
function WillMatch() {
return <h3>Matched!</h3>;
}
function NoMatch() {
let location = useLocation();
return (
<div>
<h3>
No match for <code>{location.pathname}</code>
</h3>
</div>
);
}
export default Navbar;

App.jsx页面

import React from "react";
import Navbar from "./components/Navbar";
export default function App(props) {
return (

<div>
<Navbar/>
</div>
);
}

解释是Switch组件只在其path属性的直接子级上查找,而不管它们是否为Routes。

在这种情况下,由于Switch的直接子级是不具有path属性的User.Provider,因此开关将始终只呈现该子级(开关将始终呈现至少一个子级(。

现在,User.Provider的子级将被渲染,而Switch将不再具有任何方位。这意味着现在<Route path="*" />ALWAYS渲染为您所看到的效果。

解决方案:

解决方案是仅移动User.Provider的位置以包围Switch组件。

const Navbar = React.memo(props => {

const [user, setUser] = React.useState(null);
const value = React.useMemo(() => ({user, setUser}), [user, setUser]);
const history = useHistory();

return (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/old-match">Old Match, to be redirected</Link>
</li>
<li>
<Link to="/will-match">Will Match</Link>
</li>
<li>
<Link to="/will-not-match">Will Not Match</Link>
</li>
<li>
<Link to="/also/will/not/match">Also Will Not Match</Link>
</li>
</ul>
<User.Provider value = {value}>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/old-match">
<Redirect to="/will-match" />
</Route>
<Route path="/will-match">
<WillMatch />
</Route>

<Route path="*">
<NoMatch />
</Route>                
</Switch>
</User.Provider>
</div>
</Router>
);
})

最新更新