【问题标题】:How to create bootstrap toggle buttons with React and Redux Form?如何使用 React 和 Redux Form 创建引导切换按钮?
【发布时间】:2017-08-22 17:18:03
【问题描述】:

我正在尝试使用 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>
    );
  }
}

这就是它的实现方式:

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);

如果有人能帮忙就太好了!

干杯 斯蒂芬

【问题讨论】:

    标签: reactjs react-redux redux-form


    【解决方案1】:

    您遇到的问题是您的 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 2016-03-05
      • 1970-01-01
      • 2018-05-29
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多