我创建了一个非常简单的yes / no组件,使用redux格式映射到true / false值。 单击“否”时,将在商店中更新该值,但组件不会更新。 只有在单击“是”后,才会在单击“否”时首先更新组件。
我在这里做错了什么?为什么商店里的状态没有反映在组件中?
请注意,对我的用例来说,最重要的是,没有点击任何按钮。
沙箱:
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);
答案 0 :(得分:3)
IDK究竟是如何使用redux-form的,但是你遇到了一些关于未定义的初始状态和错误值的问题;
使用format
可以处理
https://codesandbox.io/s/BL50OzNZY
format={(value) => value}
只返回值,无需额外检查。
答案 1 :(得分:1)
我认为原因是在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,以查看它是否可以解决您的问题。
答案 2 :(得分:1)
这是因为你的Field&#34; myButton&#34;初始状态等于&#34;&#34;当你点击&#34;否&#34;按钮状态更改为false但由于新状态等于前一个(&#34;&#34; == false),组件不会重新呈现。
您可以解决此问题,为您的组件传递一些与您的选项不同的初始状态(true和false)。例如,您可以将初始状态设置为任何字符串:
<SimpleForm
initialValues={{ myButton: 'notTrueOrFalse' }}
onSubmit={showResults}
/>