无法在子componentDidMount中获取this.props

时间:2018-10-25 13:26:30

标签: reactjs

在我的app.js中,我正在使用Firebase进行身份验证,并将用户保存在状态中,并作为道具发送到Home组件。

export default class App extends React.Component {

    constructor(props) {
        super(props);
        this.state={
            user:{}
        }
    }

    componentDidMount() {
        this.authListener();
    }

    authListener() {
        fire.auth().onAuthStateChanged((user) => {
            if(user) {
                this.setState({user});
            } else {
                this.setState({user:null});
            }
        })
    }
    render() {
        return (
            <div className="App">
                {this.state.user ? (<Home user={this.state.user} />) : (<Login />)}
            </div>
        )
    }
}

然后在我的Home.js中

export default class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            error: null,
            registered: false
        };
    }

    componentDidMount() {
        console.log(this.props);
    }
    render() {
        return (
            <div className="container">
                <h1>Home</h1>
            </div>
        )
    }
}

console.log(this.props)返回一个空用户:

{user: {…}}

奇怪的是,如果我仅 console.log(this),我将获得整个对象,包括具有所有信息的用户。

Home {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …}
context: {}
props: {user: Lk}
refs: {}
state: {error: null, registered: false}
updater: {isMounted: ƒ, enqueueSetState: ƒ, enqueueReplaceState: ƒ, enqueueForceUpdate: ƒ}
_reactInternalFiber: FiberNode {tag: 2, key: null, type: ƒ, stateNode: Home, return: FiberNode, …}
_reactInternalInstance: {_processChildContext: ƒ}
isMounted: (...)
replaceState: (...)
__proto__: Component

为什么我不能在componentDidMount内部访问this.props?

谢谢!

2 个答案:

答案 0 :(得分:1)

之所以会这样,是因为最初使用空的componentDidMount一个空的对象)调用了user。您只需在身份验证检查后将其设置为null

因此,由于

this.state.user最初将评估为true
this.state={
        user:{}
    }

如果将初始状态设置为具有user:null,则它将起作用,因为Home组件仅在用户存在时才会挂载。


流程如此,Home组件安装了一个空的{} user,并且componentDidMount运行并记录了一个空的user道具。然后,当您进行身份验证时,该组件不会运行componentDidMount,因为它已经是mounterdit,仅使用新的道具重新渲染。

答案 1 :(得分:0)

由于官方文档

  

您可以立即在componentDidMount()中调用setState()。它会   触发额外的渲染,但这将在浏览器之前发生   更新屏幕。这样可以保证即使render()   在这种情况下被两次调用,用户将看不到中间   州。请谨慎使用此模式,因为它经常会导致   性能问题。在大多数情况下,您应该可以分配   构造函数()中的初始状态。它可以是   当需要测量时,对于模态和工具提示之类的情况而言是必需的   DOM节点,然后渲染取决于其大小或   位置。