user12893324
user12893324

Reputation:

componentWillReceiveProps render multiple times

I am getting datas from my database using three different functions, but as I've seen componentWillReceiveProps is rerendering for three times in this case, which cause duplicating my elements in the frontend. How can I render it just once, or only object's props really change. Till now, my follows[] array objects are duplicating


class UserDashboard extends React.Component {

    state = {
        uid: this.props.userDetails.uid,
        page: 1,
        redirect: false,
        target: 15,
        selectedRole: 4,
        selectedSourceRole: 1,
        quote_nr: '',
        source_id: '',
        status_id: '',
        cost: '',
        rebate: '',
        pageLoading: false,
        date: '2222-01-02',
        therapists:[],
        globalTargets:[],
        follows:[],
        utc: new Date().toISOString().slice(0, 19).replace('T', ' '),
    }

    topProfilesUrl = 'therapists/top/profiles';
    getGlobalTargets = 'owner/targets';
    followActivities = 'user/follow/activities';

    componentDidMount = () => {
        const { getActivities,getFollowActivities,getTarget } = this;
        getActivities();
        getFollowActivities();
        getTarget();
        window.scrollTo(0, 0);
    }

    UNSAFE_componentWillReceiveProps = (newProps) => {

        let apiDat = newProps.apiDat;

        let apiData = newProps.apiData;
        if (apiData.activities && apiData.activities.success ) {
            let therapists = apiData.activities.therapists;
            let hasMore = true;
            console.log("unu")

            if (therapists.length < 10) {
                hasMore = false;
            }

            this.setState(() => ({
                therapists: this.state.therapists.concat(therapists),
                hasMore: hasMore,
                pageLoading: false
            }))
        }
        if (apiDat.targets && apiDat.targets.success) {
            console.log("doi")

            let globalTargets = apiDat.targets.globals;
            let hasMore = true;
            if (globalTargets.length < 10) {
                hasMore = false;
            }

            this.setState(() => ({
                globalTargets: this.state.globalTargets.concat(globalTargets),
            }))
        }
        if (apiData.followActivities && apiData.followActivities.success) {
            console.log("trei")

            let follows = apiData.followActivities.follows;
            let hasMore = true;
            if (follows.length < 10) {
                hasMore = false;
            }

            this.setState(() => ({
                follows: this.state.follows.concat(follows),
            }))
        }
    }
    getTarget = () => {
        this.setState({pageLoading: true}, () => { this.loadTargets() })
    }

    loadTargets = () => {

        console.log("load")
        this.props.actions.reqGetGlobalTargets({
            body: {},
            headers: null,
            resource: `${this.getGlobalTargets}?page=${this.state.page}`
        })
    }
    getFollowActivities= () => {
        this.setState({pageLoading: true}, () => { this.loadFollowActivities() })
    }
    loadFollowActivities = () => {
        console.log("load")
        this.props.actions.reqGetFollowActivities({
            body: {},
            headers: null,
            resource: `${this.followActivities}?page=${this.state.page}`
        })
    }
    renderLeads = () => {
        return (
            this.state.globalTargets.slice(0,1).map( (t, idx) => (
                t.daily_leads
            ))
        )
    }
    renderSales = () => {
        return (
            this.state.globalTargets.slice(0,1).map( (t, idx) => (
                t.daily_sales
            ))
        )
    }
    renderRatio = () => {
        return (
            this.state.globalTargets.slice(0,1).map( (t, idx) => (
                t.close_ratio
            ))
        )
    }
    getActivities = () => {
        this.setState({pageLoading: true}, () => { this.loadActivities() })
    }

    loadActivities = () => {
        this.props.actions.reqGetTherapistsTopProfiles({
            body: {},
            headers: null,
            resource: `${this.topProfilesUrl}?page=${this.state.page}`
        })
    }

    renderActivities = () => {
        const items = this.state.therapists.map( (t, idx) => (
            <tr key={t.id} className="activity-display-table">
                <td>Quote Nr.: {t.quote_nr}</td>
                <td>Source: {t.source_id}</td>
                <td>Status: {t.status_id}</td>
                <td>Cost: ${t.cost}</td>
                <td>Rebate: ${t.rebate}</td>
                <td>Date: {t.date.slice(0,10).replace(/-/g,'-')}</td>
            </tr>
        ))

        return (
            <div ref={0} className="therapist-list">
                <h2>Your Past Entries: </h2>
                { items }
            </div>
        )
    }
    renderFollowActivities = () => {

        const items = this.state.follows.map( (t, idx) => (
            <tr key={t.id} className="activity-display-table">
                <td>Quote Nr.: {t.quote_nr}</td>
                <td>Source: {t.source_id}</td>
                <td>Status: {t.status_id}</td>
                <td>Cost: ${t.cost}</td>
                <td>Rebate: ${t.rebate}</td>
                <td>Date: {t.date.slice(0,10).replace(/-/g,'-')}</td>
            </tr>
        ))

        return (
            <div ref={0} className="therapist-list">
                { items }
            </div>
        )
    }
    submitUrl = 'registerActivities';

    handleChange = (eve) => {

        let inputName = eve.target.name,
            value = eve.target.value;

        this.setState(() => {
            return {[inputName]: value}
        })
    }

    handleSubmit = () => {

        this.setState(() => {

            const acBody = {
                quote_nr: this.state.quote_nr,
                cost: this.state.cost,
                source_id: this.state.selectedSourceRole,
                status_id: this.state.selectedRole,
                date: this.state.utc,
                rebate: this.state.rebate,
                user_id:this.state.uid,
            }
           this.props.actions.reqActionsUsers(acBody, this.submitUrl);
        })

    }

    handleStatusChange = (event) => {
        let statusId = event.target.value;
        this.setState(() => ({
            selectedRole: statusId
        }))
    }

    handleSourceChange = (ev) => {
        let statusId = ev.target.value;
        this.setState(() => ({
            selectedSourceRole: statusId
        }))
    }

    render () {
        console.log(this.state.follows);

        return (
            <MainWrapper>
                <div id="user-dashboard">
                    <HeaderUser logoutRedirect="/signin"/>
                    <div className="page-background">
                        <SidebarUser page="dashboard"/>
                        {/* Page Content */}
                        <div className="inner-content">
                            <div className="top-row">
                                <h1>Salesperson Dashboard</h1>
                            </div>
                            <div className="second-row">
                            </div>
                            <div className="activity-table">
                                <table className="a">
                                    <tr>
                                        <th>Today's Targets ({this.state.utc.slice(0,10).replace(/-/g,'-')})</th>
                                        <th>Weekly Targets</th>
                                        <th>Bonus So Far This Week</th>
                                    </tr>
                                    <tr>
                                        <td>0/{this.renderLeads()} Leads Handled</td>
                                        <td>0/{this.renderLeads()*5} Leads Handled</td>
                                        <td>$0 From Leads</td>
                                    </tr>
                                    <tr>
                                        <td>0/{this.renderSales()} Sales</td>
                                        <td>0/{this.renderSales()*5} Sales</td>
                                        <td>$0 From Sales</td>
                                    </tr>
                                    <tr>
                                        <td>0/{this.renderRatio()} Close Ratio</td>
                                        <td>0/{this.renderRatio()*5} Close Ratio</td>
                                        <td>$0 From Profit Share</td>
                                    </tr>
                                </table>
                            </div>
                            <div>
                               <h2>Leads Due For A Followup</h2>
                                { this.renderFollowActivities() }

                            </div>
                            <h2 className="activity">Add Activity</h2>
                            <div className="activity-menu">
                                <input type="text"
                                       placeholder="Quote Number"
                                       name="quote_nr"
                                       onChange={this.handleChange}
                                     />
                                    <select  onChange={this.handleSourceChange}>
                                        <option value="1">Phone</option>
                                        <option value="2">Email</option>
                                        <option value="3">Live Chat</option>
                                    </select>
                                <select  onChange={this.handleStatusChange}>
                                    <option value="4">Lead</option>
                                    <option value="5">Sold</option>
                                </select>
                                <input type="text"
                                       placeholder="Cost"
                                       name="cost"
                                       onChange={this.handleChange}
                                />
                                <input type="text"
                                       placeholder={this.state.cost/20||("Recom. Rebate" + " $")}
                                       name="recRebate"
                                       readOnly
                                />
                                <input type="text"
                                       placeholder={this.state.cost/10||("Max Possible Rebate" + " $")}
                                       name="maxRebate"
                                       readOnly
                                />
                                <input type="text"
                                       placeholder="Final Rebate $"
                                       name="rebate"
                                       onChange={this.handleChange}
                                />
                            </div>
                            <ButtonRoundGradient className="activity_button" text="Add Activity" onClick={this.handleSubmit}/>
                            { this.renderActivities() }

                        </div>
                    </div>
                </div>
            </MainWrapper>
        )
    }
}

const mapStateToProps = state => ({
    apiData: state.activities,
    apiDat: state.targets,
    userDetails: state.userDetails

})
function mapDispatchToProps(dispatch) {
    return {
        actions: {
            reqGetGlobalTargets: bindActionCreators(reqGetGlobalTargets, dispatch),
            reqGetFollowActivities: bindActionCreators(reqGetFollowActivities, dispatch),
            reqGetTherapistsTopProfiles: bindActionCreators(reqGetTherapistsTopProfiles, dispatch),
            reqFetchUserDetails: bindActionCreators(reqFetchUserDetails, dispatch),
            reqActionsUsers: bindActionCreators(reqActionsUsers, dispatch),
        }
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(UserDashboard)

Upvotes: 0

Views: 395

Answers (1)

Hamid
Hamid

Reputation: 727

stringify ComponentWillRecieveProps would be called every time your props changes or your state changes, so if you want to stop duplicating, you should do this :

componentWillReceiveProps(nextProps, nextContext) {
        if (JSON.stringify(nextProps.someProps.items) !== JSON. stringify(this.state.items)){
// do something
         }
}

basically you should check if props and state of your component should react to the situation, then really render your application.

hope that helps

Upvotes: 1

Related Questions