【问题标题】:I don't understand how components are mounted我不明白组件是如何安装的
【发布时间】:2017-04-08 20:04:28
【问题描述】:

我使用模式容器/代表性组件。
我有CardContainer 组件,它从服务器获取数据并将其传递给Card 组件
容器组件:

class CardContainer extends Component {
    state = {
        'card': null
    }
    componentDidMount() {
        fetch(`${BASEURL}/api/cards/${this.props.params._id}/`)
            .then(res => res.json())
            .then(card => this.setState({'card': card}))
   }

    render() {
        return <CardDetail card={this.state.card} />
   }

表示组件:

class CardDetail extends Component {
    render() {
        return (
            <div>
                {this.props.card._id}
            </div>
        )
    }
}

在这种情况下,我有一个错误:

未捕获的类型错误:无法读取 null 的属性“_id”

因此,在父母的componentDidMount 之前调用的孩子的渲染方法。
但是在我将无状态函数组件传递给孩子的情况下,一切正常:

const FunctionChild = props => <h1>{props._id}</h1>

class CardDetail extends Component {
    render() {
        return (
            <div>
                <FunctionChild {...this.props.card} />
            </div>
        )
    }
}

我在组件rendercomponentDidMount 方法中使用console.log 来了解方法解析:

  1. 装载容器
  2. 安装孩子
  3. 挂载子函数
  4. DidMount 容器方法

所以componentDidMount 仍然最后调用,但一切正常。请有人解释我错过了什么。

【问题讨论】:

  • 没有。你的 fetch 是一个异步任务,所以你的响应是在生命周期方法执行之后。我在类似的qyery上写了一个答案:stackoverflow.com/questions/43154544/…
  • @Rajesh 我理解,但为什么它在我的示例中与 FunctionChild 子组件一起使用?
  • 我不太确定。您是否尝试过在这两种方法中记录 id
  • @IvanSemochkin 它适用于无状态组件,因为该组件每次都是一个新组件,由 props 完全描述,因此它始终具有 _id
  • 是的,我现在明白了,谢谢大家。 Stateles 组件只收到一个_id,所以它第一次收到空对象,在fetch 完成后收到_id。但是,如果我不使用 {...props} 语法而直接传递道具。它会因同样的错误而崩溃,因为 props 将是 null 第一次。

标签: javascript reactjs


【解决方案1】:

原因是,最初您将卡值定义为null,并访问 id 的值,这就是它抛出错误的原因:

无法访问 null 的属性 id

因为你是从api获取数据,所以它是asynchronous call,需要时间到return数据,直到你没有得到数据,卡的价值将是null

解决此问题的一种方法是,使用 {} 而不是 null 初始化卡,如下所示:

class CardContainer extends Component {
    state = {
        'card': {}  //change this
    }
    componentDidMount() {
        fetch(`${BASEURL}/api/cards/${this.props.params._id}/`)
            .then(res => res.json())
            .then(card => this.setState({'card': card}))
   }

    render() {
        return <CardDetail card={this.state.card} />
   }

或者在访问id值之前把check放在子组件里面,像这样:

class CardDetail extends Component {
    render() {
        return (
            <div>
                {this.props.card && this.props.card._id}
            </div>
        )
    }
}

【讨论】:

  • 谢谢你帮了我很多忙!
  • 很高兴,它帮助了你:)
猜你喜欢
  • 2022-12-16
  • 1970-01-01
  • 2012-10-11
  • 2011-06-26
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
相关资源
最近更新 更多