问题
I'm writing client side code for authentication with React and react-router. In the code below, I want to check jwt token on the server. After that, I'll get response.data.access from server and I want to set it to access variable on client. But it seems it passes false to the protected route even if it logs true in the console. How can I set access properly? I guess the problem is in asynchronous code, and setAccess function is called without waiting for axios to fetch.
// imports
function App() {
const [access, setAccess] = useState(false);
useEffect(() => {
fetch();
}, [access]);
const fetch = async () =>
await axios.get('http://localhost:7000/user/check-token')
.then(response => {
// response.data.access is a boolean variable coming from server
console.log(response.data.access)
setAccess(response.data.access);
});
return (
<Router>
<Switch>
// other routes
<Protected path='/user/dashboard' access={access}>
<Dashboard userData={userData} />
</Protected>
</Switch>
</Router>
);
}
export default App;
Here's the protected route
const Protected = ({ children, access, ...rest }) => {
return (
<div>
<Route {...rest} render={(props) => (
access === true
? children
: <Redirect to={{
pathname: '/user/login',
state: { from: props.location }
}} />
)} />
</div>
);
}
Could you please explain what is happening and what should I do?
回答1:
I have solved this problem. Well, I just added a loading screen to wait some time while data is fetching, and it solved my problem.
const Protected = ({ children, access, ...rest }) => {
return (
<div>
<Route {...rest} render={(props) => {
if (access === null) { // if access is null, the data is still being fetched
return <h1>Loading...</h1> // display loading hardcoded loading screen while it's not fetched
} else {
if (access === true) {
return children
} else {
return <Redirect to={{
pathname: '/user/login',
state: { from: props.location }
}} />
}
}
}} />
</div>
);
}
来源:https://stackoverflow.com/questions/60815245/react-doesnt-set-state-after-axios-finished-fetching