[英]React Updating parent state with API call and then update child
I want my child to rerender when my parent updates its state.当我的父母更新其 state 时,我希望我的孩子重新渲染。 Seems simple but I haven't gotten it to work.看起来很简单,但我还没有让它工作。
In App.js i make the API call in componentWillMount.在 App.js 中,我在 componentWillMount 中调用 API。 I then want "PrivateRoute" to update the state "auth" but it seems like componentDidUpdate never runs and I always get rediercted.然后我希望“PrivateRoute”更新 state“auth”,但似乎 componentDidUpdate 从未运行,我总是被重定向。
The purpose of the code is that the API call checks if the user has a valid authentication token and then sets the "isLoggedIn" state to true or false.代码的目的是 API 调用检查用户是否具有有效的身份验证令牌,然后将“isLoggedIn”state 设置为 true 或 false。 This should make the child "PrivateRoute" either redirect (if isLoggedIn is false) or render another page (if isLoggedIn is true).这应该使子“PrivateRoute”重定向(如果 isLoggedIn 为假)或呈现另一个页面(如果 isLoggedIn 为真)。
I have checked out a lot of other similar questions but no solution has worked this far.我检查了很多其他类似的问题,但到目前为止还没有解决方案。
My app.js:我的 app.js:
import React, { Component } from "react";
import {
BrowserRouter as Router,
Route,
Switch,
Link,
Redirect,
} from "react-router-dom";
import axios from "axios";
import PrivateRoute from "./components/PrivateRoute";
// Pages
import IndexPage from "./pages/index";
import HomePage from "./pages/home";
class App extends Component {
constructor() {
super();
console.log("Constructor");
this.state = {
loggedInStatus: false,
test: "TEST",
};
}
// Checks if user is logged in
checkAuth() {
let token = localStorage.getItem("token");
let isLoggedIn = false;
if (token === null) token = "bad";
console.log("Making API call");
// API call
axios
.get("http://localhost:8000/authentication/checkAuth", {
headers: { Authorization: "token " + token },
})
.then((res) => {
console.log("Updateing state");
this.setState({ loggedInStatus: true });
})
.catch((error) => {
console.log("Updating state");
this.setState({ loggedInStatus: false });
});
return isLoggedIn;
}
componentWillMount() {
this.checkAuth();
}
render() {
//console.log("Render");
// console.log("isLoggedIn: ", this.state.loggedInStatus);
return (
<Router>
<Switch>
<PrivateRoute
exact
path="/home"
component={HomePage}
auth={this.state.loggedInStatus}
/>
<Route exact path="/" component={IndexPage} />
</Switch>
</Router>
);
}
}
export default App;
PrivateRoute.jsx: PrivateRoute.jsx:
import { Redirect } from "react-router-dom";
import React, { Component } from "react";
class PrivateRoute extends Component {
state = {};
constructor(props) {
super(props);
this.state.auth = false;
}
// Update child if parent state is updated
componentDidUpdate(prevProps) {
console.log("Component did update");
if (this.props.auth !== prevProps.auth) {
console.log("Child component update");
this.setState({ auth: this.props.auth ? true : false });
}
}
render() {
console.log("Props: ", this.props);
console.log("State: ", this.state);
//alert("this.props.auth: ", this.props.auth);
//alert("TEST: ", this.props.test);
if (this.props.auth) {
return <h1>Success!</h1>;
//return <Component {...this.props} />;
} else {
return (
<Redirect
to={{ pathname: "/", state: { from: this.props.location } }}
/>
);
}
}
}
export default PrivateRoute;
checkAuth should be sync, if you want auth status before first-ever render in the component. checkAuth 应该是同步的,如果你想在组件中首次渲染之前获得身份验证状态。
Your checkAuth will return instantly, making the auth status always false.您的 checkAuth 将立即返回,使身份验证状态始终为假。
async checkAuth() {
try {
let token = localStorage.getItem("token");
let isLoggedIn = false;
if (token === null) token = "bad";
const res = await axios
.get("http://localhost:8000/authentication/checkAuth", {
headers: {Authorization: "token " + token},
})
console.log("Updateing state");
this.setState({loggedInStatus: true});
} catch (e) {
// for non 2XX axios will throw error
console.log("Updating state");
this.setState({loggedInStatus: false});
}
}
async componentWillMount() {
await this.checkAuth();
}
In the child component, you have to set state from props.在子组件中,您必须从道具中设置 state。
constructor(props) {
super(props);
this.state.auth = props.auth;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.