子组件未从父组件获取状态

时间:2020-01-18 14:23:01

标签: javascript reactjs react-native

在App.js中,我有以下代码;

constructor() {
    super();
    this.state = {
        isLoggedIn: false,
        username: "",
    }
}

componentDidMount() {
    let isLoggedIn = false;
    let username = "";

    if (localStorage.getItem("token")) {
        fetch("https://localhost:8000/user", {
            method: "POST",
            headers: {
                "Authorization": `Bearer ${localStorage.getItem("token")}`
            }
        }).then(response => response.json()).then(response => {
            if (response.success) {
                isLoggedIn = true;
                username = response.username;
            } else {
                isLoggedIn = false;
                username = "";
                localStorage.removeItem("token");
            }

            this.setState({
                isLoggedIn : isLoggedIn,
                username: username
            })
        })
    }
}

render() {

    return (
       <Navbar username={this.state.username}/>
    )
}

通过控制台记录输出,一旦componentDidMount被调用,处于状态的用户名将被分配。在Navbar.js中;

constructor(props) {
    super(props);
    this.state = {
        navComponents: []
    }
}

componentDidMount()  {
    console.log(this.props.username);
    let navComponents = [];
    if (this.props.username === "") { //Not Signed In.
        navComponents.push(
            <ul className="Navbar-list">
                <li className="Navbar-item">
                    <Link to="/register" className="Navbar-link">Sign Up</Link>
                </li>
                <li className="Navbar-item">
                    <Link to="/login" className="Navbar-link">Log In</Link>
                </li>
            </ul>
        );
    } else {
        navComponents.push(
            <p>Hello, {this.props.username}</p>
        )
        navComponents.push(
            <ul className="Navbar-item">
                <Link to="/signout" className="Navbar-link">Sign Out</Link>
            </ul>
        )
    }
    this.setState({
        navComponents : navComponents
    })
}

我认为应该从App获取用户名。但是,用户名总是 一个空字符串(App的初始状态)。我不确定为什么在组件中安装了Navbar后就不更新。

2 个答案:

答案 0 :(得分:1)

您做错了,不是您的render函数应该为组件做标记, 尝试这样应该可以正常工作。

constructor(props) {
    super(props);
}



render(){
    return (
            {this.props.username ? 
             <> 
              <p>Hello, {this.props.username}</p>
              <ul className="Navbar-item">
                <Link to="/signout" className="Navbar-link">Sign Out</Link>
             </ul>
             </>
             : 
            <ul className="Navbar-list">
                <li className="Navbar-item">
                    <Link to="/register" className="Navbar-link">Sign Up</Link>
                </li>
                <li className="Navbar-item">
                    <Link to="/login" className="Navbar-link">Log In</Link>
                </li>
            </ul>})
}

答案 1 :(得分:0)

原因很简单,因为componentDidMount中的Navbar仅在username具有值之前被触发一次。

该流程所发生的情况如下

  1. App.js render被调用
  2. App.js componentDidMount被调用
  3. App.js消防API调用
  4. Navbar render被调用
  5. Navbar componentDidMount被调用
  6. 第3步的结果返回

现在,由于componentDidMount中的Navbar仅会被触发一次,因此您将始终看到this.props.username在此为空。最简单的解决方案之一是通过componentDidUpdate而不是componentDidMount

处理逻辑