代码之家  ›  专栏  ›  技术社区  ›  Toby Weed

在包装组件之前,停止反应高阶组件的安装?

  •  2
  • Toby Weed  · 技术社区  · 6 年前

    我有一个与身份验证相关的hoc,它包装组件。在包装的组件中,我需要一个由hoc设置的用户属性。但是,在子组件中,我调用componentdidmount中的prop,得到错误:

    TypeError: Cannot read property 'identity' of null
    

    它告诉我用户属性(具有identity属性)没有及时设置。 这里是hoc:

    export default function withAuth(AuthComponent) {
        return class AuthWrapped extends Component {
            constructor() {
                super();
                this.state = {
                    user: null
                };
                this.Auth = new AuthService();
            }
    
            async componentDidMount() {
                try {
                    const profile = await this.Auth.getProfile(); //Returns a decoded JWT token containing with 'identity':'test'
                    console.log(profile.identity); //prints 'test' twice
                    this.setState({
                        user: profile
                    });
                    console.log(this.state.user); //prints the full profile including 'identity':'test' once and null once
                }
            }
    
            render() {
                const user = this.state.user;
                console.log(user); //prints null once and the correct profile once
                return (
                    <AuthComponent history={this.props.history} user={this.state.user} />
                );
            }
        };
    
     }
    

    注意console.logs每个打印两次。 这是包装好的组件:

    class Account extends Component {
        componentDidMount() {
            axios.get('/user/' + this.props.user.identity).then(res => { //This is the line which triggers the error.
                //do something
            });
        }
    
        render() {
                    <div><AnotherComponentWrappedBySameHOC/></div>
                );
            }
    }
    
    export default withAuth(Account);
    

    当我删除还由withauth包装的另一个组件时,console.logs只运行一次。有道理。但是,仍然打印的日志是打印空值的日志。换句话说,错误的日志。

    基本上,我认为这意味着componentdidmount调用withauth花费的时间太长,并且在componentdidmount调用帐户之后完成。尽管我尽力了,但我没有办法。有什么想法吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   supra28    6 年前

    你可以等到你有了用户,然后把孩子变成

      render() {
                const user = this.state.user;
                console.log(user); //prints null once and the correct profile once
                return (<div>
                   {user && <AuthComponent history={this.props.history} user={this.state.user} />}
                </div>);
            }
        };
    

    这将仅在以下情况下渲染子组件 user 有一些数据