Redux-Form, как использовать formValueSelector с динамическими именами полей?

Я использую избыточную форму и пытаюсь создать компонент поля следующим образом:

<Rating
  stop={10}
  initialRate={selector(this.props.state, 'age')}
  onRate={(rate) => this.onRateChange(rate)}
  onChange={(value) => { this.changeRate("name", value) } }
/>
<span className="label label-default" id="label-onrate">{this.state.label}</span>

<Field
  name="age"
  type="number"
  component={renderField2}
/>

RateForm = reduxForm({
  form: 'rateForm'
})(RateForm);

const selector = formValueSelector('rateForm');

const mapStateToProps = state => {
  return {
  };
};

export default connect(mapStateToProps)(RateForm);

Проблема, с которой я столкнулся, заключается в том, что initialRate не работает... следующее не возвращает значение:

selector(this.props.state, 'age')

Поскольку имя поля будет динамическим, мне нужно избегать:

определение имени конкретного поля в mapStateToProps.

Что я делаю неправильно с избыточной формой formValueSelector, чтобы не предоставить initialRate значение?


person AnApprentice    schedule 18.07.2017    source источник
comment
какую версию редукционной формы вы используете   -  person Shubham Khatri    schedule 18.07.2017
comment
6.6.3 - моя версия редукционной формы. Это проблема?   -  person AnApprentice    schedule 18.07.2017
comment
Вы уверены, что передаете state в качестве реквизита для своего компонента RateForm?   -  person Ritesh Bansal    schedule 18.07.2017
comment
Не могли бы вы уточнить, являются ли имена полей динамическими? Будет ли это массив полей? Можете ли вы разветвить jsfiddle.net/sherin81/d82a1tao и предоставить базовый образец?   -  person Sherin Mathew    schedule 18.07.2017


Ответы (3)


Вы можете сделать что-то вроде этого:

import { getFormValues } from 'redux-form/immutable'

getFormValues вернет значения, сохраненные в соответствии с предоставленным form name.

const mapStateToProps = state => {
  const formState = getFormValues('rateForm')(state)
  console.log('formState...', formState)
  return formState 
}

Это работает нормально для меня. Я получаю значения всех компонентов Field, отображаемых для этой формы, то есть rateForm в вашем случае. Для получения более подробной информации вы можете перейти здесь.

person Ritesh Bansal    schedule 18.07.2017

Из документов:

Функция, возвращаемая из formValueSelector(), имеет следующую структуру:

селектор(состояние:Объект, ...поле:Строка)

 state : Object [required]

Глобальное состояние Redux, присвоенное mapStateToProps.

 ...field : String [required]

Поле или поля, которые вы хотите выбрать. Если вы укажете только одно имя поля, функция вернет значение этого поля. Если вы укажете более одного имени поля, он вернет поля объекта, отображающие значения. Если ваше поле «глубокое» (т. е. имеет один или несколько . в имени), структура, которую вы получите, также будет глубокой. например Если ваши поля 'a.b' и 'a.c', результирующая структура будет { a: { b:'bValue', c: 'cValue' } }.

В вашем случае вы ничего не возвращаете из mapStateToProps,

Вы могли бы вместо того, чтобы иметь селектор в компоненте Rating, иметь его в mapStateToProps и использовать его как

<Rating
  stop={10}
  initialRate={selector(this.props.state, 'age')}
  onRate={(rate) => this.onRateChange(rate)}
  onChange={(value) => { this.changeRate("name", value) } }
/>


const selector = formValueSelector('rateForm');

const mapStateToProps = state => {
  return {
      state
  };
};

В приведенном выше примере предполагается, что props доступны для компонента Rating.

person Shubham Khatri    schedule 18.07.2017
comment
Верно, но у меня есть динамическое имя поля в качестве упоминания, поэтому я не могу этого сделать. Как это может работать с именем динамического поля? - person AnApprentice; 18.07.2017
comment
Вы имеете в виду, что у вас может быть несколько таких полей компонента Rating, и в приведенном выше случае вы хотите, чтобы initialRating был равен значению возраста. В этом случае проверьте обновление - person Shubham Khatri; 18.07.2017
comment
у меня будет несколько. Я просто не хотел перечислять все 5+ полей выше. - person AnApprentice; 18.07.2017
comment
Спасибо, это работает, но я выбираю ответ Ритеша, поскольку он более эффективен. - person AnApprentice; 18.07.2017
comment
проверьте и этот ответ:) в другом компоненте"> stackoverflow.com/questions/44513287/ - person Shubham Khatri; 18.07.2017

@Ritesh указывает мне на решение:

const formName = "form";
const form = reduxForm<MyFormFields, MyFormProps>({form: formName});    

function MyForm() {
   return (
     <div>
        Here your form
     </div
   );

}

const mapStateToProps = (state: any) => ({
    initialValues: {
    },
    getFormFieldValue: (field: string) => {
        const selector = formValueSelector(formName);
        return selector(state, field);
    }
});

const mapDispatchToProps = (dispatch: Dispatch) => ({
    changeField: (field: string, value: any) => dispatch(change(formName, field, value)),
    resetForm: () => dispatch(reset(formName)),
});

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(form(MyForm)));

Надеюсь, это может быть полезно для кого-то!

person Luca Davanzo    schedule 12.02.2020