简体   繁体   中英

How to call method in child component only once after parent state update

I have one parent and one child. The parent retrieves data (data is named blurts) using a fetch request, and sends the data via props to the child component. The child component is a lazy-loader component that only displays 6 records at a time as the user scrolls.

The lazy component creates its own state (array) based on the number of parent component records, which determines whether a record should be visible. All isVisible properties are set to false initially.

componentDidMount() in lazy component:

componentDidMount() {
    var isVisibleArray = this.props.blurts.map(item => {
        return false;
    });
    this.setState({ isVisible: isVisibleArray });
    this.PushBlurtArray();
    window.addEventListener('scroll', this.LazyLoader);
}

Then, PushBlurtArray() method is called in order to set the first 6 records to visible. This method is also called each time the user scrolls to the sixth record. Internal state in the lazy-loader keeps track of this and sets 6 more to visible as needed.

PushBlurtArray() in lazy component:

PushBlurtArray() {
    // Initial values that keep track of lazy state.
    var renderCount = this.state.lazyState.skipCount,
        numRendered = this.state.numberRendered,
        isVisibleUpdate = this.state.isVisible;

        // Logic to get the next 6 (or less) blurts in the array and set isVisible to true
        // each time this method is called by the lazyloader method.
        for(let i=numRendered; i<renderCount; i++) {
            if (this.props.blurts[i]) {
                isVisibleUpdate[i] = true;
                numRendered++;
            }
        }

        // Update state accordingly so the loop iterates over the proper numerical
        // sequence keeping the blurts in order of consecutive sixes.
        this.setState(prevState => ({
            lazyState: {
                lzyLoading: true,
                skipCount: prevState.lazyState.skipCount + prevState.lazyState.skipInc,
                skipInc: 6,
                skipDb: prevState.lazyState.skipDb
            },
            isVisible: isVisibleUpdate,
            numberRendered: numRendered
        }));
}

This works properly up to a point. The restraint I'm having trouble with is that the parent component only pulls an initial count of 42 records. Then, once the lazy loader has iterated through all 42, I call a method in the parent that mounts another 42 records to its state, which in turn re-renders the lazy-loader. In theory this should go on indefinitely without issue.

The problem I'm having is that PushBlurtArray() needs to get called once the 42 additional records has been added to the parent state. If I call PushBlurtArray() in the render() method, or in componentDidUpdate(), it ends up calling PushBlurtArray() repetitively which pretty much screws up the entire ordeal.

I need a way to call PushBlurtArray() just once, after the 42 records has been added to state in the parent component.

You can check the transition of your data inside componentDidUpdate . In this instance you want to check for the length of your array to determine when it changes.

componentDidUpdate(props) {
  if (
    (this.props.blurts.length > 0 && !props.blurts.length) ||
    this.props.blurts.length !== props.blurts.length
  ) {
    this.PushBlurtArray();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM