我正在尝试使用React,Redux Form和Bootstrap(reactstrap)创建一个可切换的按钮组。
我所做的已经正确更新了redux表单数据。
问题在于按钮颜色属性应该在"成功"之间切换。和"中学"。现在它确实在第一个切换上设置了颜色,但是在我之后点击另一个按钮时不会更新。
这是我的渲染组件:
import React from 'react';
import classNames from 'classnames';
import { Label, FormGroup, ButtonGroup, Button } from 'reactstrap';
import FontAwesome from 'react-fontawesome';
export default class buttonOptions extends React.PureComponent {
static propTypes = {
input: React.PropTypes.object,
buttons: React.PropTypes.any,
label: React.PropTypes.string,
meta: React.PropTypes.shape({
touched: React.PropTypes.bool,
error: React.PropTypes.any,
})
};
constructor(props) {
super(props);
this.toggleOption = this.toggleOption.bind(this);
}
toggleOption(val) {
if (!this.props.input.value.length) this.props.input.value = [];
// option per buttongroud is always limited to 1
// remove previously selected options
for (let b of this.props.buttons) {
if (b.value !== val && this.props.input.value.indexOf(b.value) > -1) {
this.props.input.value.splice(this.props.input.value.indexOf(b.value), 1)
}
}
// push the new option and update state
this.props.input.value.push(val);
this.props.input.onChange(this.props.input.value)
}
render() {
const { input, buttons, label, meta: { touched, error }} = this.props;
const labelStyles = {width: '100%', marginBottom: '0'};
return (
<FormGroup>
<Label style={labelStyles}>{label}</Label>
<ButtonGroup>
{
buttons.map((b) => {
return (
<Button
key={b.title}
color={classNames({
success: input.value.indexOf(b.value) > -1,
secondary: input.value.indexOf(b.value) === -1,
})}
role="button"
onClick={() => { this.toggleOption(b.value) }}
>
{b.title}
</Button>
)
})
}
</ButtonGroup>
</FormGroup>
);
}
}
&#13;
这就是它的实施方式:
import React from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './AdWizard.css';
import cx from 'classnames';
import FontAwesome from 'react-fontawesome';
import { Field, reduxForm } from 'redux-form'
import { Row, Col, FormGroup, Label, Button } from 'reactstrap';
import buttonOptions from '../FormComponents/buttonOptions';
class Step2 extends React.Component {
constructor(props) {
super(props);
this.workingtimes = [
{
title: "Vollzeit",
value: "Vollzeit",
selected: true
},
{
title: "Teilzeit",
value: "Teilzeit",
selected: false
}
]
}
render() {
const { handleSubmit, previousPage } = this.props;
return (
<form onSubmit={handleSubmit}>
<Row className="justify-content-center">
<Col xs="12" sm="6">
<Field
label="Arbeitszeit"
name="arbeitszeit"
buttons={this.workingtimes}
component={buttonOptions}
/>
</Col>
</Row>
</form>
)
}
}
Step2 = reduxForm({
form: 'posting',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true
})(Step2);
export default withStyles(s)(Step2);
&#13;
如果有人可以提供帮助,那会很棒!
干杯 斯蒂芬
答案 0 :(得分:0)
您遇到的问题是您的toggleOption
功能不纯*
这意味着它正在改变this.props.input.value
,而不是创建一个值基于它的新数组 - 简单来说,总是创建一个新的引用!
由于大多数React代码都对纯函数调用非常敏感,所以 你必须将该函数转换为纯函数,以便redux-form实际上看到你改变了数组:
toggleOption (b) {
let newValue;
const currValue = this.props.input.value || [];
if (currValue.includes(b.value)) {
// value already exists in array, let's remove it from there
newValue = currValue.filter(val => val !== b.value);
} else {
// value doesn't exist in array, let's add it there
newValue = currValue.concat([b.value]);
}
this.props.input.onChange(newValue);
}
.filter()
和.concat()
之类的数组方法在这里是你的好处:它们返回新的数组实例,而不是改变现有的数组。
您的代码使用的是.push()
和.splice()
,这些方法很糟糕,因为它们会改变现有的数组。
您可以看到一个小型演示here。
*您可以阅读有关此主题的更多信息here。