提问者:小点点

当父组件在响应中更新其数组时,子组件不更新


我在父react组件中有一个项目列表,其中添加了新项目和更新项目。子组件将接收道具中的项目并进行渲染。

父状态更新时,子组件不会更新其值。我需要更新状态的子组件状态中的"组件WillReceiveProps"?正确的做法是什么。

Code Example 
// parent component 
import React, { Component } from "react";
import TestList from '../controls/testlistview'

export default class TestView extends Component {
    constructor(props) {
        super();
        this.state = {
            items: []
        };
    }

    render() {
        return (<div>
            <button onClick={this.addItem.bind(this)}> Add item</button>
            <button onClick={this.changeFirstItemText.bind(this)}> Change item</button>
            <TestList items={this.state.items} index={index}/>
        </div>);
    }

    addItem() {
        var items = this.state.items.map(s=> s);

        items.push('new one');
        this.setState({
            items: items
        });
    }



    changeFirstItemText() {
        var items = this.state.items.map(s=> s);
        items[0] = "changed text";
        this.setState({
            items: items
        });
    }
}



//Child component
import React, { Component } from "react";

export default class TestList extends Component {
    constructor(props) {
        super();
        debugger;
        this.state = {
            rootNodes: props.items
        };
    }

    componentWillReceiveProps(nextProps){
        debugger;
    }

    render() {
        var items = this.state.rootNodes.map((s) => {
            return <div>{s}</div>;
        });
        return <div>{items}</div>;
    }
}

共3个答案

匿名用户

而不是

render() {
        var items = this.state.rootNodes.map((s) => {
            return <div>{s}</div>;
        });
        return <div>{items}</div>;
    }

你从道具中得到物品

render() {
        var items = this.props.items.map((s) => {
            return <div>{s}</div>;
        });
        return <div>{items}</div>;
    }

您不必再次将道具分配给TestList状态,否则您将需要再次从TestList执行setState(),以便再次触发渲染。(这不是必要的步骤)

http://codepen.io/kossel/pen/ObQLoR

匿名用户

在TestList类中,您不应该将道具分配给组件的状态-这是在React中导致重大问题的可靠方法,也是您在此处出现问题的原因。看看我的答案,为什么这是个坏主意。

如果你把你的测试项目改成以下,那么它应该可以正常工作。

export default class TestList extends Component {
    constructor(props) {
        super();
        debugger;
    }

    componentWillReceiveProps(nextProps){
        debugger;
    }

    render() {
        var items = this.props.items.map((s) => {
            return <div>{s}</div>;
        });
        return <div>{items}</div>;
    }
}

匿名用户

原因是您正在通过子组件的状态创建ui元素。有两种方法可以解决此问题:
1。像这样更新componentWillReceiveProps()函数中的状态值

 componentWillReceiveProps(newProps){
        this.setState({
            rootNodes: newProps.items
        });
}

2.直接从props值创建ui元素,如下所示-

render() {
    var uiItems = this.props.items.map((item) => {
        return <div>{item}</div>;
    });
    return (<div>{uiItems}</div>);
}