ReactJS:父子部分更新

时间:2016-10-31 16:02:48

标签: reactjs

在我的特定用例中,如何在父母和子组件之间进行通信时,我有点麻烦。

我有一个子组件,使用外部库渲染一些点。

我目前正在做的是实现componentDidMount / Update并使用外部lib渲染 this.props.points (这是父组件提供的数组)中的点。

渲染点包括循环遍历它们并调用ExternalLib.addPoint(point)之类的东西。

我想做什么,而不是每次 this.props.points 更改时循环遍历所有点,使父组件将各个点添加(或删除)到子组件。< / p>

在父组件中调用类似 this.refs.myChild.addPoint(point)之类的内容是否友好?

还有其他技术可以实现这样的目标吗?

更新

这里有一些代码(https://jsfiddle.net/69z2wepo/61366/):

const ExternalLib = {

    addPoint: function(el, point) {
        var li = document.createElement("li");
        li.innerHTML = point;
        el.appendChild(li);
    }
}

class Child extends React.Component {

    componentDidMount() {
        this.renderPoints();
    }

    componentDidUpdate() {
        this.renderPoints();
    }

    renderPoints() {
        const el = this.refs.points;
        el.innerHTML = '';
        this.props.points.forEach(function(point) {
            ExternalLib.addPoint(el, point);
        });
    }

    render() {
        console.log('render')
        return (
            <div>
                <ul ref="points"></ul>
            </div>
        );
    }
}

class Parent extends React.Component {

    constructor() {

        super();

        this.state = {
            points: []
        };
    }

    addPoint() {

        const points = this.state.points.slice();

        points.push((new Date()).getTime());

        this.setState({
            points: points
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.addPoint.bind(this)}>Add Point</button>
                <Child points={this.state.points} />
            </div>
        );
    }
}

ReactDOM.render(
    <Parent />,
    document.getElementById('container')
);

这是简化的,因为在这个例子中我可以使用 map 直接生成标记并利用React的部分DOM更新 - 外部lib会做一些额外的东西。不在这个问题的范围内。

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您想干扰React渲染过程,可以编写shouldcomponentupdate

在您的孩子中,如果您shouldcomponentupdate返回false并致电ExternalLib.addPoint(point),那么它应该可以胜任:

shouldComponentUpdate(nextProps){
  //comparePoints() is a function able to find if a new point is present in the list, comparing existing used points with new one
  var newPoint = comparePoints(this.props.points, nextProps.points)

  if(newPoint){
    ExternalLib.addPoint(newPoint);
    //forbide re-render
    return false;
  }

  //enable other update
  return true;
}