Javascript 使用API调用更新父状态,然后更新子状态
我希望我的孩子在父母更新其状态时重新启动。看起来很简单,但我还没把它用上 在App.js中,我在componentWillMount中进行API调用。然后,我希望“PrivateRoute”更新状态“auth”,但似乎componentDidUpdate从未运行,我总是被重新检测 代码的目的是API调用检查用户是否具有有效的身份验证令牌,然后将“isLoggedIn”状态设置为true或false。这将使子“PrivateRoute”重定向(如果isLoggedIn为false)或呈现另一个页面(如果isLoggedIn为true) 我已经检查了很多其他类似的问题,但到目前为止还没有解决方案 我的app.js:Javascript 使用API调用更新父状态,然后更新子状态,javascript,reactjs,state,Javascript,Reactjs,State,我希望我的孩子在父母更新其状态时重新启动。看起来很简单,但我还没把它用上 在App.js中,我在componentWillMount中进行API调用。然后,我希望“PrivateRoute”更新状态“auth”,但似乎componentDidUpdate从未运行,我总是被重新检测 代码的目的是API调用检查用户是否具有有效的身份验证令牌,然后将“isLoggedIn”状态设置为true或false。这将使子“PrivateRoute”重定向(如果isLoggedIn为false)或呈现另一个页面
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;
import React,{Component}来自“React”;
进口{
BrowserRouter作为路由器,
路线,,
转换
链接
重新使用
}从“反应路由器dom”;
从“axios”导入axios;
从“/components/PrivateRoute”导入PrivateRoute;
//页数
从“/pages/index”导入IndexPage;
从“/pages/home”导入主页;
类应用程序扩展组件{
构造函数(){
超级();
console.log(“构造函数”);
此.state={
loggedInStatus:false,
测试:“测试”,
};
}
//检查用户是否已登录
checkAuth(){
让token=localStorage.getItem(“token”);
设isLoggedIn=false;
如果(token==null)token=“坏”;
log(“进行API调用”);
//API调用
axios
.get(“http://localhost:8000/authentication/checkAuth", {
标题:{授权:“令牌”+令牌},
})
。然后((res)=>{
日志(“更新状态”);
this.setState({loggedInStatus:true});
})
.catch((错误)=>{
日志(“更新状态”);
this.setState({loggedInStatus:false});
});
返回伊斯洛格丁;
}
组件willmount(){
this.checkAuth();
}
render(){
//控制台日志(“呈现”);
//log(“isLoggedIn:”,this.state.loggedInStatus);
返回(
);
}
}
导出默认应用程序;
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;
从“react router dom”导入{Redirect};
从“React”导入React,{Component};
类PrivateRoute扩展组件{
状态={};
建造师(道具){
超级(道具);
this.state.auth=false;
}
//如果父级状态已更新,则更新子级
componentDidUpdate(prevProps){
日志(“组件已更新”);
if(this.props.auth!==prevProps.auth){
日志(“子组件更新”);
this.setState({auth:this.props.auth?true:false});
}
}
render(){
log(“Props:,this.Props”);
log(“State:,this.State”);
//警报(“this.props.auth:,this.props.auth”);
//警报(“测试:”,this.props.TEST);
if(this.props.auth){
回归成功!;
//返回;
}否则{
返回(
);
}
}
}
导出默认私有路由;
如果希望在组件中首次渲染前获得身份验证状态,则checkAuth应为同步
您的checkAuth将立即返回,使auth状态始终为false
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();
}
在子组件中,必须从道具设置状态
constructor(props) {
super(props);
this.state.auth = props.auth;
}
如果希望在组件中首次渲染之前获得身份验证状态,则checkAuth应该是同步的 您的checkAuth将立即返回,使auth状态始终为false
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();
}
在子组件中,必须从道具设置状态
constructor(props) {
super(props);
this.state.auth = props.auth;
}
使用
componentDidMount
而不是componentWillMount
此外,您的PrivateRoute中不需要“this.state.auth”,因为您可以只使用prop(this.props.auth)@RedBaron componentDidMount将不起作用,因为在第一次渲染时它将重定向。请使用componentDidMount
而不是componentWillMount
此外,您的PrivateRoute中不需要“this.state.auth”,因为您可以只使用该道具(this.props.auth)@RedBaron componentDidMount无法工作,因为在第一次渲染时它将重定向。我这样更改了代码,但它似乎仍然在更改“loggedInStatus”之前呈现重定向。@S.Martinsson在子组件中,您没有从构造函数中的道具设置状态。您正在componentDidUpdate中设置状态,该状态将在第一次渲染调用后执行,在渲染函数中,您的身份验证状态将始终为false。我已经更新了我的代码,您必须更改子组件中的构造函数以从props设置auth。同样的问题,由于某种原因,props.auth在构造函数运行时似乎是错误的。我通过添加一个“加载”状态来解决问题,该状态在API调用完成之前呈现一个空白页!我这样更改了代码,但它似乎仍然在更改“loggedInStatus”之前呈现了重定向。@S.Martinsson在子组件中,您没有从构造函数中的props设置状态。您正在componentDidUpdate中设置状态,该状态将在第一次渲染调用后执行,在渲染函数中,您的身份验证状态将始终为false。我已经更新了我的代码,您必须更改子组件中的构造函数以从props设置auth。同样的问题,由于某种原因,props.auth在构造函数运行时似乎是错误的。我通过添加一个“加载”状态来解决问题,该状态在API调用完成之前呈现一个空白页!