将默认值传递给禁用的输入字段,但它阻止输入到 Redux-Forms 中的启用字段

Passing default values to disabled input fields, but it is preventing input into enabled fields in Redux-Forms

从昨天开始就一直在为此苦苦挣扎,但这已经是我能做到的最接近工作的了。只是尝试用从服务器接收到的数据预填充输入字段。看起来很简单,但我显然遗漏了一些东西。

虽然我可以让字段填充,但它几乎锁定了表单中的所有字段以防止编辑——那些没有预先填充但应该是可编辑的字段。

这是我目前拥有的内容的一小部分 "works"。用户名是服务器可以用值响应的用户名,如果它使用 renderDisabledField:它会用 value 填充该字段并禁用它,因此无法对其进行编辑。否则,它应该是可编辑的。另一方面,密码字段应该始终是可编辑的。

componentWillReceiveProps() {
    this.props.initialize(this.props.acctVal);
}

renderField(field) {
    const { 
        placeholder,
        type,
        name,
        meta: {
            touched, 
            error 
        } 
    } = field;

    return (
        <div className='form-group'>
            <input 
                className='form-control' 
                type={type}
                placeholder={placeholder}
                {...field.input} 
            />
            <div className='text-danger'>
                {touched ? error : ""}
            </div>
        </div>
    );
}

renderDisabledField(field) {

    const { 
        type,
        name,
        placeholder,
    } = field;

    return (
        <div className='form-group'>
            <input 
                className='form-control' 
                type={type}
                placeholder={placeholder}
                disabled
                {...field.input} 
            />
        </div>
    );
}

render() {
    if (this.props.permitRender) {
        const { handleSubmit } = this.props;
        return (
            <div>
                <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>

                    {this.renderAlert()}

                    <h4>Set Username</h4>
                    <p>Please enter the username you would like associated with your account. It must be at least 5 characters in length.</p>

                    <Field
                        name='username'
                        type='text'
                        placeholder='Enter Username'
                        onBlur={this.validateUsername.bind(this)}
                        component={this.props.acctVal.username ? this.renderDisabledField : this.renderField}
                    />

                    <hr />

                    <h4>Set New Password</h4>
                    <p>Type your new password twice. </p>
                    <p>It must be a minimum of 8 characters in length and contain at least:</p>
                    <ol>
                        <li>One uppercase character</li>
                        <li>One special character</li>
                        <li>One number</li>
                    </ol>

                    <Field
                        name='password1'
                        type='password'
                        placeholder='Enter New Password'
                        component={this.renderField}
                    />

                    <Field
                        name='password2'
                        type='password'
                        placeholder='Confirm Password'
                        component={this.renderField}
                    />

                    <hr />

                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
                <br />
            </div>
        );            
    } else if (!this.props.permitRender) {
        return ( 
            <Loading />
        );
    } 
}

function mapStateToProps(state) {
    return { 
        errorMessage: state.auth.error,
        permitRender: state.auth.permitRender,
        questions: state.auth.questions,
        acctVal: state.auth.acctVal
    };
}

SetupUser = reduxForm({
    form: 'setup_user',
    touchOnChange: true,
    validate
})(SetupUser);
SetupUser = connect(mapStateToProps, { checkUsername, setupUser, verifyKey })(SetupUser);
export default SetupUser;

编辑:

差点忘了减速器:

import {
    ACCT_VALUES
} from '../actions/authentication';

export default function(state = {}, action) {
    switch(action.type) {
        case ACCT_VALUES:
            return { ...state, 
                acctVal: {
                    username: action.payload.data.username,
                    company: action.payload.data.company_name[0].company_name,
                    firstname: action.payload.data.first_name,
                    lastname: action.payload.data.last_name,
                    email: action.payload.data.email,
                    phone: action.payload.data.phone
                },
            };
        default:
            return state;
    }

    return state;
}

我已经尝试过在生命周期的不同点进行各种渲染:

https://reactjs.org/docs/react-component.html#the-component-lifecycle

也尝试按照这些进行操作,但未能获得预期的结果:

https://redux-form.com/6.7.0/examples/initializefromstate/

编辑:绕圈子并重试我已经尝试过的东西。

这可以在字段中获取值,但是当您尝试将 stateprops 传递到 initialValues 时会中断。

function mapStateToProps(state) {
    return { 
        errorMessage: state.auth.error,
        permitRender: state.auth.permitRender,
        questions: state.auth.questions,
        acctVal: state.auth.acctVal
    };
}

SetupUser = reduxForm({
    form: 'setup_user',
    touchOnChange: true,
    validate,
    initialValues: {username: 'test1'}
}, mapStateToProps)(SetupUser);
SetupUser = connect(mapStateToProps, { checkUsername, setupUser, verifyKey })(SetupUser);
export default SetupUser;

用这个和大约一打其他变体得到 `Cannot read 属性 'props' of undefined:

initialValues: this.props.acctVal
initialValues: {this.props.acctVal}
initialValues: {username: this.props.acctVal.username}

人们认为是必要的次要细节。

在这种情况下,我标记为 acctVal 的内容实际上应该 称为 initialValues,如文档所述:

function mapStateToProps(state) {
    return { 
        errorMessage: state.auth.error,
        permitRender: state.auth.permitRender,
        questions: state.auth.questions,
        initialValues: state.auth.acctVal
    };
}

SetupUser = reduxForm({
    form: 'setup_user',
    touchOnChange: true,
    validate,
})(SetupUser);
SetupUser = connect(mapStateToProps, { checkUsername, setupUser, verifyKey })(SetupUser);
export default SetupUser;

然后就可以摆脱:

componentWillReceiveProps() {
    this.props.initialize(this.props.acctVal);
}