繁体   English   中英

子组件没有从父组件获取状态

[英]Child component does not get state from parent

我在 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 的初始状态)。 我不确定为什么在 App 中安装组件后导航栏不更新。

你做错了,是不是你的渲染函数假设为一个组件做标记,像这样尝试应该可以正常工作。

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>})
}

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

流程中发生的事情如下

  1. 正在调用App.js render
  2. App.js componentDidMount被调用
  3. App.js触发 API 调用
  4. Navbar render被调用
  5. Navbar componentDidMount被调用
  6. Step 3 返回的结果

现在因为Navbar componentDidMount只会被触发一次,因此你总是会看到this.props.username在那里是空的。 最简单的解决方案之一是在componentDidUpdate而不是componentDidMount处理您的逻辑

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM