El Anonimo
El Anonimo

Reputation: 1870

Return one or two objects with getDerivedStateFromProps?

My component receives profile and errors from the parent. Within the component static getDerivedStateFromProps sets the new state should the component receive new data from the parent.

...
constructor(props) {
        super(props);

        this.state = {
            displaySocialInputs: false,
            handle: '',
            company: '',
            website: '',
            location: '',
            status: '',
            skills: '',
            githubusername: '',
            bio: '',
            twitter: '',
            facebook: '',
            linkedin: '',
            youtube: '',
            instagram: '',
            errors: {}
        };

        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }
...

static getDerivedStateFromProps(nextProps) {
        if (nextProps.errors) {
            console.log('nextProps.errors:', nextProps.errors);
            return { errors: nextProps.errors };
        }

        if (nextProps.profile.profile) {
            const profile = nextProps.profile.profile;

            // bring skills array back to csv
            const skillsCsv = profile.skills.join(',');

            // if a profile field wasn't provided set it to an empty string
            profile.company = !isEmpty(profile.company) ? profile.company : '';
            profile.website = !isEmpty(profile.website) ? profile.website : '';
            profile.location = !isEmpty(profile.location) ? profile.location : '';
            profile.githubusername = !isEmpty(profile.githubusername) ? profile.githubusername : '';
            profile.bio = !isEmpty(profile.bio) ? profile.bio : '';
            profile.social = !isEmpty(profile.social) ? profile.social : {};
            profile.twitter = !isEmpty(profile.social.twitter) ? profile.social.twitter : '';
            profile.facebook = !isEmpty(profile.social.facebook) ? profile.social.facebook : '';
            profile.linkedin = !isEmpty(profile.social.linkedin) ? profile.social.linkedin : '';
            profile.youtube = !isEmpty(profile.social.youtube) ? profile.social.youtube : '';
            profile.instagram = !isEmpty(profile.social.instagram) ? profile.social.instagram : '';

            // set component state
            return {
                handle: profile.handle,
                company: profile.company,
                website: profile.website,
                location: profile.location,
                status: profile.status,
                skills: skillsCsv,
                githubusername: profile.githubusername,
                bio: profile.bio,
                twitter: profile.twitter,
                facebook: profile.facebook,
                linkedin: profile.linkedin,
                youtube: profile.youtube,
                instagram: profile.instagram
            };
        }

        return null;
    }

The code above prevents the profile object from displaying on the page. When the

if (nextProps.errors) {
            console.log('nextProps.errors:', nextProps.errors);
            return { errors: nextProps.errors };
        }

part is commented out the profile data displays Ok but the errors data cannot display.

How do I get both errors and profile object to display? On my component submit the component field data submits to the parent so if all the required fields are not empty there should be no errors coming in.

The complete repo is on https://github.com/ElAnonimo/DevConnector/blob/master/client/src/components/common/ProfileForm.js

UPDATE 1

The parent component EditProfile.

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import ProfileForm from '../common/ProfileForm';
import { createProfile, getCurrentProfile } from '../../actions/profileActions';

class EditProfile extends Component {
    constructor(props) {
        super(props);

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

    componentDidMount() {
        this.props.getCurrentProfile();
    }

    onSubmit(profileData) {
        this.props.createProfile(profileData, this.props.history);
    }

    render() {
        return <ProfileForm profile={this.props.profile} errors={this.props.errors} onSubmit={this.onSubmit} />
    }
}

EditProfile.propTypes = {
    profile: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired,
    createProfile: PropTypes.func.isRequired,
    getCurrentProfile: PropTypes.func.isRequired
};

const mapStateToProps = (state) => ({
    profile: state.profile,
    errors: state.errors
});

export default connect(mapStateToProps, { createProfile, getCurrentProfile })(withRouter(EditProfile));

Upvotes: 2

Views: 872

Answers (1)

Mayank Shukla
Mayank Shukla

Reputation: 104529

To return both the data, create an object first then add the key-values in respective if conditions and finally return that object. By that way it will execute both if conditions.

Like this:

static getDerivedStateFromProps(nextProps) {

    let obj = {};

    if (nextProps.errors) {
        obj.errors = nextProps.errors;
    }

    if (nextProps.profile.profile) {
        const profile = nextProps.profile.profile;

        // bring skills array back to csv
        const skillsCsv = profile.skills.join(',');

        // if a profile field wasn't provided set it to an empty string
        profile.company = !isEmpty(profile.company) ? profile.company : '';
        profile.website = !isEmpty(profile.website) ? profile.website : '';
        profile.location = !isEmpty(profile.location) ? profile.location : '';
        profile.githubusername = !isEmpty(profile.githubusername) ? profile.githubusername : '';
        profile.bio = !isEmpty(profile.bio) ? profile.bio : '';
        profile.social = !isEmpty(profile.social) ? profile.social : {};
        profile.twitter = !isEmpty(profile.social.twitter) ? profile.social.twitter : '';
        profile.facebook = !isEmpty(profile.social.facebook) ? profile.social.facebook : '';
        profile.linkedin = !isEmpty(profile.social.linkedin) ? profile.social.linkedin : '';
        profile.youtube = !isEmpty(profile.social.youtube) ? profile.social.youtube : '';
        profile.instagram = !isEmpty(profile.social.instagram) ? profile.social.instagram : '';

        // set component state
        const temp = {
            handle: profile.handle,
            company: profile.company,
            website: profile.website,
            location: profile.location,
            status: profile.status,
            skills: skillsCsv,
            githubusername: profile.githubusername,
            bio: profile.bio,
            twitter: profile.twitter,
            facebook: profile.facebook,
            linkedin: profile.linkedin,
            youtube: profile.youtube,
            instagram: profile.instagram
        };

        obj = { ...obj, ...temp };
    }

    return obj;
}

Upvotes: 2

Related Questions