【问题标题】:Child component's props not updating when state changes状态更改时子组件的道具不更新
【发布时间】:2018-05-03 19:05:26
【问题描述】:

我正在使用拖放来实例化反应类,但由于某种原因,父组件的状态没有传递给子组件。孩子甚至没有被重新渲染,尝试过 shouldComponentUpdate 和 componentWillReceiveProps。

家长相关代码:

dragEnd(e) {
    e.preventDefault();
    let me = this;

    let el = (
        <Pie key={ Date.now() * Math.random() } yAxisData={ me.state.yAxisData } legendData={ me.state.legendData } />
    )

    this.setState({
        cells: this.state.cells.concat(el),
    });
}

所以,在放置时,创建,然后渲染看起来像:

render() {
    <div className = { "insights-data" } onDrop={ this.dragEnd } onDragOver={ this.preventDefault }>
        { this.state.cells }
    </div>
}

这一切都很好,但是现在当我更改传递给 this.state.yAxisData 和/或 this.state.legendData 的数据时,它不会在子组件上调用渲染。

这是子组件的渲染:

    render() {
    return (
        <div className="insights-cell">
            <ReactECharts
                option={ this.create() }
                style={{ position: "absolute", top: 0, bottom: 0, left: 0, right: 0, height: "100%" }}
                theme="chalk"
                notMerge={ true }
            />
        </div>
    )
}

有什么想法吗?我认为可能存在绑定问题,但似乎不是这样,因为我正在使用 me = this.它甚至没有重新渲染子组件。

【问题讨论】:

  • 嗯,你举个例子here我帮你看看。
  • 哦,伙计,要重新创建我在小提琴中所做的事情需要做很多工作。我可能不得不这样做,但暂时尽量避免。让我看看我是否可以做一个简单的例子并重新创建我的问题。
  • 当然,一个简单的例子就足够了。
  • @stevelacerda7 在dragEnd 函数中,您已经在使用预定义的道具创建元素数组。您应该在每次渲染时创建一个新元素。
  • 但是,它应该正确引用状态对象,如果它们只是引用状态对象,为什么我必须重新创建它们?我不会在任何地方覆盖我的状态对象。

标签: javascript reactjs


【解决方案1】:

您已经在dragEnd 函数中创建元素,方法是将道具传递给它并将它们存储到数组中。因此数组this.state.cells 包含已声明元素的数组。因此它不能更新状态变化。您应该在每次渲染时渲染一个新的元素数组。

只需在this.state.cells 中推送拖动元素的一些必要细节,然后在每次渲染时遍历该数组。

dragEnd(e) {
    e.preventDefault();

    let el = draggedElementType

    this.setState({
        cells: this.state.cells.concat(el),
    });
}

在渲染中,遍历这个数组并返回所需的元素。

render() {
    <div className = { "insights-data" } onDrop={ this.dragEnd } onDragOver={ this.preventDefault }>
        { this.state.cells.map((cell, index) => {
           if (cell === "pie") {
           return (<Pie key={index} yAxisData={ me.state.yAxisData } legendData={ me.state.legendData } />);
           }
           else if (){...
        )}
    </div>
}

【讨论】:

  • 好的,谢谢,但我不能使用 因为我不知道它是不是这样,它不能是硬编码,因为它可以是 Pie或线或其他东西。我是否必须做一个 if/else 条件,只存储“pie”,如果 id==="pie" 然后使用
  • 如果保持密钥一致,那么 react 可以更好地优化这一点。我会使用let el = "pushed element " + Date.now() * Math.random(); - 当像这样映射时:cells.map(el =&gt; &lt;Pie key={el} ... /&gt;)
  • @stevelacerda7 您需要将该值存储在this.state.cells 数组中(即无论是饼图还是线等)。
  • 好的,所以我实际上不能存储元素,但存储一些东西以便我知道我需要创建什么元素。说得通。感谢您的帮助。
  • 我不会在每次渲染时生成随机密钥。你的表现消失了。确保在 dragEnd 方法中生成一次密钥。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
相关资源
最近更新 更多