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}
/>
我创建了一个非常简单的是/否组件,它使用 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}
/>