redux 表单组件不反映商店状态

redux form component not reflecting store state

我创建了一个非常简单的是/否组件,它使用 redux 形式映射到真/假值。 单击 "No" 时,商店中的值会更新,但组件不会更新。 只有先单击“是”后,组件才会在单击“否”时更新。

我在这里做错了什么?为什么商店中的状态没有反映在组件中?
请注意,对于我的用例来说,最初没有单击任何按钮很重要。

沙盒:

https://codesandbox.io/s/r06VKjB4K

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

const buttonStyle = {
  width: '50px',
  display: 'inline-block',
  border: '1px solid green',
  margin: '5px',
  padding: '5px',
  cursor: 'pointer',
  textAlign: 'center',
};

const ButtonBar = ({ options, input }) =>
  <div style={{ display: 'block' }}>
    {options.map(x =>
      <div
        onClick={() => {
          input.onChange(x.value);
        }}
        style={{
          ...buttonStyle,
          ...{
            backgroundColor: input.value === x.value ? x.selected : 'white',
          },
        }}
      >
        {x.displayName}
      </div>,
    )}
  </div>;

const SimpleForm = props => {
  return (
    <form>
      <div style={{ display: 'inline-block', border: '1px solid grey' }}>
        <Field
          name="myButton"
          component={ButtonBar}
          options={[
            {
              value: true,
              displayName: 'Yes',
              selected: 'green',
            },
            {
              value: false,
              displayName: 'No',
              selected: 'red',
            },
          ]}
        />
      </div>
    </form>
  );
};

export default reduxForm({
  form: 'simple', // a unique identifier for this form
})(SimpleForm);

我知道 redux-form 是如何工作的,但是你有一些关于未定义的初始状态和错误值的问题; 使用 format 你可以处理

https://codesandbox.io/s/BL50OzNZY

     format={(value) => value}

只是 returns 值,无需额外检查。

我认为原因是在redux-form代码的某处,它最初将空字符串和false视为同一事物并且不会触发重新渲染。看起来 redux-form 使用了这个 deepEquals 函数定制器:

const customizer = (obj, other) => {
  if (obj === other) return true
  if (
    (obj == null || obj === '' || obj === false) &&
    (other == null || other === '' || other === false)
  )
    return true

  if (obj && other && obj._error !== other._error) return false
  if (obj && other && obj._warning !== other._warning) return false
}

您可以尝试将初始值设置为 false,看看是否能解决您的问题。

发生这种情况是因为您的字段 "myButton" 的初始状态等于“”,当您单击 "No" 按钮时,状态变为 false,但由于新状态等于前一个状态("" == false) 组件不会重新渲染。

您可以通过为您的组件传递一些不同于您的选项(true 和 false)的初始状态来解决此问题。例如,您可以将初始状态设置为任何字符串:

<SimpleForm
    initialValues={{ myButton: 'notTrueOrFalse' }}
    onSubmit={showResults}
  />

https://codesandbox.io/s/0R1rw63nV