最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Prevent child component from rerendering based on change of state in parent - Stack Overflow

programmeradmin4浏览0评论

I'm having a heck of time with this. I do NOT want my child to re-render when the parents state changes. I've tried to use shouldComponentUpdate in the child ponent, but for some reason that's not even being invoked.

My issue is this. I have several charts on a grid, I want to update one of the charts configuration settings, which I pass as a prop to the ponent. The parent, which they all share, updates that childs config, but in the process, the config changes and thus they all re-render.

Why isn't shouldComponentUpdate being invoked? It gets invoked on the parent, so I'm assuming it is invoked where the state changes???

My code looks something like:

Parent - has selectDataType with setState Child1 - calls selectDataType which was passed down as a prop, which re-renders Child2 - no changes to it's props, but re-renders, which I need to stop

Parent:

selectDataType(e) {
    e.stopPropagation();

    var cellId = e.currentTarget.dataset.id;
    var cellValue = e.currentTarget.childNodes[0].value;

    var newCells = [];

    newCells = this.state.cells.map(function (cell, i) {
        var newObj = Object.assign({}, cell);

        if (cellId == cell.id) {
            newObj['dataType'] = cellValue;
        }

        return newObj;
    });

    this.setState({
        cells: newCells
    });

    return;
}

Child1:

export default class Pie extends React.Component {
    constructor(props) {
    super(props);

    this.create = this.create.bind(this);
}

shouldComponentUpdate() {
    return false;
}

create() {
    return {
        //some data
    }
}

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

}

Child2: exactly like Child1

I'm having a heck of time with this. I do NOT want my child to re-render when the parents state changes. I've tried to use shouldComponentUpdate in the child ponent, but for some reason that's not even being invoked.

My issue is this. I have several charts on a grid, I want to update one of the charts configuration settings, which I pass as a prop to the ponent. The parent, which they all share, updates that childs config, but in the process, the config changes and thus they all re-render.

Why isn't shouldComponentUpdate being invoked? It gets invoked on the parent, so I'm assuming it is invoked where the state changes???

My code looks something like:

Parent - has selectDataType with setState Child1 - calls selectDataType which was passed down as a prop, which re-renders Child2 - no changes to it's props, but re-renders, which I need to stop

Parent:

selectDataType(e) {
    e.stopPropagation();

    var cellId = e.currentTarget.dataset.id;
    var cellValue = e.currentTarget.childNodes[0].value;

    var newCells = [];

    newCells = this.state.cells.map(function (cell, i) {
        var newObj = Object.assign({}, cell);

        if (cellId == cell.id) {
            newObj['dataType'] = cellValue;
        }

        return newObj;
    });

    this.setState({
        cells: newCells
    });

    return;
}

Child1:

export default class Pie extends React.Component {
    constructor(props) {
    super(props);

    this.create = this.create.bind(this);
}

shouldComponentUpdate() {
    return false;
}

create() {
    return {
        //some data
    }
}

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

}

Child2: exactly like Child1

Share Improve this question asked May 8, 2018 at 22:14 stevenlacerdastevenlacerda 1,1873 gold badges10 silver badges21 bronze badges 7
  • shouldComponentUpdate() : Returning false does not prevent child ponents from re-rendering when their state changes. – dave Commented May 8, 2018 at 22:23
  • How do you render the children in the parent? A possible reason is not giving a static key property to the child ponents. If they're given, say, a random key every time they're rendered, then they'll pletely unmount and remount with its new parent properties. So the child ponent isn't updating, it's remounting. Hence shouldComponentUpdate won't be called – Jayce444 Commented May 8, 2018 at 22:26
  • Can you show us the parent's render? – Leandro Soares Commented May 8, 2018 at 22:32
  • ahhhh...@Jayce444 that seems reasonable. Let me check it out and get back to you. – stevenlacerda Commented May 8, 2018 at 22:38
  • 1 Thanks @Jayce444. It solved my problem too. Been pulling my hair out on this one. – snowykz Commented Jun 3, 2021 at 9:53
 |  Show 2 more ments

2 Answers 2

Reset to default 7

Make sure your children are given a static key prop (as for all arrays of ponents). If they're given a random key, then when the parent re-renders it'll give all the children a new random key (different from their old one). This will make React think it's a pletely different ponent, so the existing one will pletely unmount and be remounted (with the new properties). So the child ponent isn't updating, it's remounting. Hence shouldComponentUpdate won't be called.

You might find answers here, for both classes and hooks: ReactJS: setState on parent inside child ponent

Short answer for hooks would be:

  • Send parent state and setState in child prop. Lets call those parentState and setParentState
  • In child ponent:
    • have a useEffect which only does something when parentState is updated:
    useEffect(() => {
        props.parentStateSetter(childStateValueYouWantToTrack);
    }, [props.parentState, childStateValueYouWantToTrack]);

You should check out the link for more information

发布评论

评论列表(0)

  1. 暂无评论