【问题标题】:Return one or two objects with getDerivedStateFromProps?用 getDerivedStateFromProps 返回一两个对象?
【发布时间】:2019-02-20 07:09:03
【问题描述】:

我的组件从父组件接收profileerrors。在组件内static getDerivedStateFromProps 设置组件从父组件接收到新数据时的新状态。

...
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;
    }

上面的代码阻止profile 对象显示在页面上。当

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

部分被注释掉了profile数据显示OK但errors数据无法显示。

如何同时显示 errorsprofile 对象?在我的组件上提交组件字段数据提交给父级,因此如果所有必填字段都不为空,则不应有 errors 进来。

完整的 repo 位于https://github.com/ElAnonimo/DevConnector/blob/master/client/src/components/common/ProfileForm.js

更新 1

父组件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));

【问题讨论】:

    标签: reactjs getderivedstatefromprops


    【解决方案1】:

    要返回两个数据,首先创建一个对象,然后在各自的if 条件中添加键值,最后返回该对象。通过这种方式,它将同时执行if 条件。

    像这样:

    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;
    }
    

    【讨论】:

    • 组件状态没有obj 属性。所有单个字段都设置为状态。请查看编辑。
    • obj 是一个会与状态对象合并的对象,const obj={}; return obj;return {}; 是一样的,只是写法不同:)
    • 最终我们需要返回一个带有键值对的对象,我们想要在状态中更新的键。如果您遇到任何问题,请尝试该代码。
    • 它似乎工作正常。另一件事:访问另一个页面时如何摆脱errors对象然后返回组件页面?字段错误仍然显示。
    • 再添加一个条件为else if (!nextProps.errors) { obj.errors = ''; } 它将删除错误,如果错误是一个对象然后分配空对象:)
    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 2015-06-03
    • 2014-05-27
    • 2014-05-22
    相关资源
    最近更新 更多