Значение поля обновления Redux-Form от внешнего взаимодействия

У меня есть редукционная форма, связанная с моим состоянием приложения, и все, кажется, отлично работает. Я могу получить данные и загрузить их в свою форму, а затем отправить данные и получить нужные метаданные ...

Однако у меня есть настраиваемое взаимодействие (палитра цветов), которому необходимо на лету изменять значение управляемого поля. Все, что я пробую, изменяет экран, но не состояние формы redux, т.е. когда я отправляю форму, я получаю только исходные данные поля, а не новые данные, показанные в форме.

Версия ниже передает свойства поля компоненту и пытается использовать состояние компонента ColorSelect в качестве значения поля. Я также попытался создать создателя действий, но тот же результат и намного больше кода, чем в этом примере ...

Примечание: response@^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>
        );
    }
}


person Mike Priest    schedule 23.01.2017    source источник


Ответы (1)


Вы можете использовать mapDispatchToProps response-redux вместе с _ 2_ средство создания действий для достижения желаемого:

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)
person gustavohenke    schedule 24.01.2017
comment
@gustavohenke добавьте обертку для отправки - person zahar_g; 13.08.2017
comment
Это не требуется: github. com / reactjs / react-redux / blob / master / docs / - person gustavohenke; 14.08.2017
comment
Что касается 2020 года, я попытался сделать это без диспетчера, и изменение было внесено, но не было уведомлено, мое промежуточное ПО не уловило никаких изменений, ни Redux DevTools. Смена упаковки с отправкой решила мою проблему. - person Mateus Wolkmer; 27.02.2020