2017-01-23 15 views
8

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

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

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

Примечание: [email protected]^15.4.2, [email protected]^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> 
 
     ); 
 
    } 
 
}

ответ

10

Вы можете использовать реагировать-перевождь-х mapDispatchToProps вместе с change action creator для того, чтобы достичь того, чего вы хотите:

import { Component } from "react"; 
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) 
+0

Отлично! Огромное вам спасибо - работал шарм. –

+1

@ gustavohenke, пожалуйста, добавьте упаковку отправки –

+0

Не нужно: https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options – gustavohenke