Redux-Form update field value from external interaction

情到浓时终转凉″ 提交于 2019-11-29 17:50:34

问题


I have a redux-form connected to my application state and everything seems to work great. I can fetch data and load it into my form, then submit data and get the metadata I want...

However, I have a custom interaction (a color picker) that needs to change the value of a managed Field on the fly. Everything I try will change the screen, but not the redux form state i.e. when I submit the form I just get the original field data and not the new data shown in the form.

The version below is passing the field props to the component and trying to use the ColorSelect component state as the field value. I have also tried creating an action creator, but same result and much much more code that this example...

Note: react@^15.4.2, react-redux@^5.0.2, redux-form@^6.4.3

ES6: CollectionForm.js

...
import ColorSelect from './ColorSelect';


class CollectionForm extends Component {

    /**
     * On form submit accepted
     * @param values
     */
    onSubmit(values){

        //See screenshot for evidence
        log('Updating collection:', 'warn', values);

        //values.color is grey and not yellow!
        this.props.dispatch(updateCollection(values));
        return;
    }

    /**
     * Form render
     * @return {JSX}
     */
    render()
    {
        const { handleSubmit, submitting } = this.props;

        return (
            <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                <Field component={renderTextInput} name="name" type="text" label="Name"/>
                <Field component={ColorSelect} name="color" />

                <div class="field-buttons right-align group">
                    <Button type="submit" disabled={submitting} primary>
                        Save
                    </Button>
                </div>
            </form>
        );
    }
};

//Redux form decorator
CollectionForm = reduxForm({ form: 'collectionForm' })(CollectionForm)

// State connector
CollectionForm = connect(
    state => ({
        initialValues: state.collections.activeCollection

    }), //MapStatetoProps
    {
        onLoad: fetchCollection
    }   //mapActionToProps
)(CollectionForm);

export default CollectionForm;

ES6: CollectionForm.js

import React, { Component } from 'react'
import { Field, reduxForm, SubmissionError } from 'redux-form';

const colors = [
    'grey', 'green', 'yellow', 'orange', 'red', 'purple', 'blue'
];

export default class ColorSelect extends Component {

    constructor(props){
        super(props);

        this.state = {
            selectedColor : this.props.input.value //Set to current <Field> input value
        };

        this.onSelect = this.onSelect.bind(this);
        this.renderColor = this.renderColor.bind(this);
    }

    /**
     * Color picker selected
     * @param color
     */
    onSelect(color){
        this.setState({ selectedColor: color }); //Sets correct state here
    }

    /**
     * Render a color list item
     * @param color
     * @return {JSX}
     */
    renderColor(color){

        const select = this.state.selectedColor === color ? "active" : "";
        const klass = color + " " + select;

        return <li key={color}>
            <a class={klass} onClick={(event) => this.onSelect(color)}></a>
        </li>
    }

    /**
     * Render color list action
     * @return {JSX}
     */
    render(){

        //Override field value with colorSelected state
        
        return (
            <div>
                <input {...this.props.input} value={this.state.selectedColor} name="color" type="text" label="Color" />

                <div class="color-selector">
                    <ul>
                        {colors.map((color) => this.renderColor(color) )}
                    </ul>
                </div>
            </div>
        );
    }
}

回答1:


You can use react-redux's mapDispatchToProps together with the change action creator in order to achieve what you want:

import { Component } from "react";
import { connect } from "react-redux';
import { change } from "redux-form";

class ColorSelect extends Component {
  // ...other stuff in this class...

  renderColor (color) {
    const { selectColor } = this.props;
    return <li key={color}><a onClick={() => selectColor(color)}></a></li>;
  }
}

export default connect(null, {
  selectColor: color => change( "yourFormName", "yourFieldName", color )
})(ColorSelect)


来源:https://stackoverflow.com/questions/41809474/redux-form-update-field-value-from-external-interaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!