0

I have a react component which we are calling conditional based on flag.

In ComplianceCards js - I have divided the function based on flag runTriggered.

runTriggered ? UpdateCards() : createCards()

ParentComponent ComplianceCards - when It goes inside createCards function all works fine, But when UpdateCard() is getting called I see the latest values what I am passing, But in child component it still show old props values.

const UpdateCards = () => {
            let view;
            /**
             * @param {*} deviceId
             * get the compliance details
             */

            let agag = getComplianceDetails(this.props.deviceId)
            .then(parsedData => {
                if (parsedData) {
                    return parsedData;
                }
                else {
                    console.log ("This function is not returning anything. Let's check why!")
                }
            })
            .catch((error)=>{
                console.log ("Let's see what's going on here -> ", error);
            });


            agag.then(data => {
                console.log("agag data", data);
                if (data) {
                    this.setState({
                        updatedCardData: data
                    });

                    const { updatedCardData } = this.state
                    if (updatedCardData) {
                        console.log("if come inside");
                        view = (
                            <div>
                                <DnxCardLayout name="cardlayout" style={{ padding: "5px" }}>
                                    <div className="cards_flex_container">
                                        {updatedCardData &&
                                            updatedCardData.map(newCard => {
                                                return (
                                                    <ComplianceCard
                                                        cardData={newCard}
                                                        key={newCard.complianceType}
                                                        handleClick={this._handleClick}
                                                        storeArchiveData={this.storeArchiveData}
                                                    />
                                                );
                                            })}
                                    </div>
                                </DnxCardLayout>
                            </div>
                        );
                        return view;
                    } else {
                        console.log("updatedCardData else come inside");
                    }
                } else {
                    console.log("else come inside");
                }
            })
            .catch((error)=>{
                console.log ("Let's see what's going on here -> ", error);
            });
        };

when UpdateCards() get called my console prints -

agag data `data`
ComplianceCards.js:504 if come inside

I can see here data is latest updated value but inside s\child components it's old values or props.

My Parent component ComplianceCards-

export default class ComplianceCards extends Component {

    /**
     * Constructor
     * @param {} props
     */
    constructor(props) {
        super(props);
        this.state = {
            // some states
        };
    }

    /**
     * Component DidMount
     */
    componentDidMount() {
    }

    /**
     * Component will un-mount
     */
    componentWillUnmount() {
    }

    /**
     * render function
     */
    render() {
    }
}

I have refactored based on comments and for clear understanding. I hope This will help.

This is my Child component's ComplianceCard code -

import React, { Component } from "react";
// some other dependencies

export default class ComplianceCard extends Component {
    constructor(props) {
        super(props);
        this.state = {
            latestArchivedVersion: null,
            networkProfiles: null,
            showImageLoader:false,
            showConfigLoader:false
        };
    }

    /**
     * Get data for each complianceType
     */
    componentDidMount() {
        let { cardData, storeArchiveData } = this.props;
        const complianceType = cardData.complianceType;
        const deviceUuid = cardData.deviceUuid;
        if (complianceType == labels.runningConfig) {
            this.setState( {
                showConfigLoader:true
            })
            getArchiveConfigDetails(deviceUuid).then(data => {
                if (data) {
                    this.setState({
                        latestArchivedVersion: data[data.length - 1]
                    });
                    if (storeArchiveData) {
                        storeArchiveData(data);
                    }
                    this.setState( {
                        showConfigLoader:false
                    })
                }
            });
        } else if (complianceType == labels.networkProfile) {
            // TODO, do we really need this? we need to re-trigger the details api to get all NETWORK_PROFILE data
            getComplianceDetails(deviceUuid, {
                complianceType: labels.networkProfile
            }).then(data => {
                if (data) {
                    this.setState({
                        networkProfiles: [...data]
                    });
                }
            });
        } else if (complianceType == labels.softwareImage) {
            this.setState( { 
                showImageLoader: true
            });
            getImageDetails(deviceUuid).then(data => {
                if (data) {
                    this.setState({
                        imageDetails: data,
                        showImageLoader: false
                    });
                }
            });
        }
    }

    componentDidUpdate(prevProps) {
        if (prevProps.cardData !== this.props.cardData) {
            let { cardData } = this.props;
        }
    }

    componentWillReceiveProps(nextProps) {
        this.setState({ data: nextProps.data });  
      }

    /**
     * Component will un-mount
     */
    componentWillUnmount() {

    }

    /**
     * Handles click event
     * @param {*} target
     */
    handleClick = target => {
        let { cardData, handleClick } = this.props;
        const complianceType = cardData.complianceType;
        handleClick(complianceType, cardData);
    };


    /**
     * Component render function
     */
    render() {
        let { cardData } = this.props;
        // render function code
    }
}

please point out the issue, Thanks..

Javascript Coder
  • 5,691
  • 8
  • 52
  • 98

2 Answers2

0

You are not returning anything from your if clause, hence React won't start rendering those cards.

const createCards = runTriggered => {
            let newCards, view = null;
            /**
             * @param {*} deviceId
             * get the compliance details
             */
            let agag = getComplianceDetails(this.props.deviceId).then(data => {
                if (data) {
                    return data;
                }
                // .then afterwards will fail if no data is present
            });
            if (runTriggered) {
                // No return here, assuming createCards is treated as a promise you can try:
                // return agag.then(...
                agag.then(data => {
                    newCards = data;
                    view = (...);
                    return view;
                });
            } else {
                view = (...);
                return view;
            }
        };
    ```
BerndS
  • 409
  • 2
  • 8
  • I am returning `return view;` inside `if (runTriggered) {` and same with else also, can you please let me know where exactly you mean – Javascript Coder Apr 24 '20 at 07:29
  • You are returning it in `agag.then(() => {return view})` indeed, but this does not mean it's returned from `createCards`. The if clause returns nothing currently, you could try returning `agag.then(() => ...)` but I don't think you're treating createCards as an asynchronous function – BerndS Apr 24 '20 at 07:35
  • I have updated the question for clear understanding, so I can convey the problem, Please check. – Javascript Coder Apr 24 '20 at 09:30
  • First of all, I don't understand where `runTriggered ? UpdateCards() : createCards()` is being called in your code. In the render function? If I understand your problem correctly, you are now facing a state update that is not propagated to the children? That could be because of the following piece of code: `this.setState({ updatedCardData: data }); const { updatedCardData } = this.state` setState is asynchrounous, so retrieving updatedCardData from state after setting it has a high chance of being the old data. Try just using `data` instead of getting it from state – BerndS Apr 24 '20 at 12:43
0
let agag = getComplianceDetails(this.props.deviceId)
    .then(data => data.json())
    .then(parsedData =>{
        if (parsedData) {
            return parsedData;
        }
        else{
            console.log ("This function is not returning anything. Let's check why!")
        }
    })
    .catch((error)=>{
        console.log ("Let's see what's going on here -> ", error);
    });
Maf
  • 696
  • 1
  • 8
  • 23