Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用API调用更新父状态,然后更新子状态_Javascript_Reactjs_State - Fatal编程技术网

Javascript 使用API调用更新父状态,然后更新子状态

Javascript 使用API调用更新父状态,然后更新子状态,javascript,reactjs,state,Javascript,Reactjs,State,我希望我的孩子在父母更新其状态时重新启动。看起来很简单,但我还没把它用上 在App.js中,我在componentWillMount中进行API调用。然后,我希望“PrivateRoute”更新状态“auth”,但似乎componentDidUpdate从未运行,我总是被重新检测 代码的目的是API调用检查用户是否具有有效的身份验证令牌,然后将“isLoggedIn”状态设置为true或false。这将使子“PrivateRoute”重定向(如果isLoggedIn为false)或呈现另一个页面

我希望我的孩子在父母更新其状态时重新启动。看起来很简单,但我还没把它用上

在App.js中,我在componentWillMount中进行API调用。然后,我希望“PrivateRoute”更新状态“auth”,但似乎componentDidUpdate从未运行,我总是被重新检测

代码的目的是API调用检查用户是否具有有效的身份验证令牌,然后将“isLoggedIn”状态设置为true或false。这将使子“PrivateRoute”重定向(如果isLoggedIn为false)或呈现另一个页面(如果isLoggedIn为true)

我已经检查了很多其他类似的问题,但到目前为止还没有解决方案

我的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;
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调用完成之前呈现一个空白页!