【问题标题】:How to change the state of an item affected by onClick in array?如何更改数组中受 onClick 影响的项目的状态?
【发布时间】:2018-04-12 18:13:32
【问题描述】:

我正在创建一个页面,我需要在其中选择多个按钮(如过滤器,我将用于下一页)。

这些按钮的信息来自一个数组,我使用 .map () 来挂载按钮列表。

我的问题是如何仅更改被单击按钮的状态。现在的样子,当我点击时,所有按钮都处于活动状态。

我该如何解决这个问题?

谢谢。

import React from 'react';
import { Link } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import messages from './messages';

import { getLevel, getDiscipline } from '../../functions';

import template from './index.pug';

export default class ConfigAssessment extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function

  constructor(props){
    super(props);
    this.state = {
      level: getLevel(),
      discipline: getDiscipline(),
      active: '',
      first_click: true,
    }
  }

  changeActive = () => {
    if (this.state.first_click === true) {
      this.setState({
        active: 'active',
        first_click: false
      });
    } else {
      this.setState({
        active: '',
        first_click: true,
      });
    }
  }


  render() {
    return(
<div className="configuration">
      <div className="config-title">
        <i className="ti-settings" />
        <h2>
          <FormattedMessage {...messages.configAssessment} />
        </h2>
      </div>
      <div className="config-items">
        <div className="form-group">
          <label>
            <FormattedMessage {...messages.level} />
          </label>
          <div className="row">
            {this.state.level.map((level, i) => (
              <div className="col-xs-1 col-md-4 col-lg-3" key={level.id}>
                <button
                  className={`btn btn-light-gray btn-block ${this.state.active}`}
                  id={level.id}
                  onClick={this.changeActive}
                >
                  {level.level}
                </button>
              </div>
              ))}
          </div>
        </div>
        <div className="form-group">
          <label>
            <FormattedMessage {...messages.discipline} />
          </label>
          <div className="row">
            { this.state.discipline.map((discipline, i) => (
              <div className="col-xs-1 col-md-4 col-lg-3" key={i}>
                <button
                  className={`btn btn-light-gray btn-block ${this.state.active}`}
                  onClick={this.changeActive}
                >
                  {discipline.discipline}
                </button>
              </div>
              ))}
          </div>
        </div>
        <div className="form-group">
          <label>
            <FormattedMessage {...messages.selectQuestion} />
          </label>
          <div className="row">
            <div className="col-xs-1 col-md-4 col-lg-3">
              <button
                className={`btn btn-light-gray btn-block ${this.state.active}`}
                onClick={this.changeActive}
              >
                <FormattedMessage {...messages.typeAutomatic} />
              </button>
            </div>
            <div className="col-xs-1 col-md-4 col-lg-3">
              <button
                className={`btn btn-light-gray btn-block ${this.state.active}`}
                onClick={this.changeActive}
              >
                <FormattedMessage {...messages.typeManual} />
              </button>
            </div>
          </div>
        </div>
        <div className="form-group fg-right">
          <Link className="btn btn-warning" to="#">
            <FormattedMessage {...messages.createAssessment} />
          </Link>
        </div>
      </div>
    </div>
  );
  }
}

【问题讨论】:

  • 您的代码可以用于单个按钮。如果您使用多个按钮,则更新您的代码和逻辑。在您的 changeActive('{lavel.id}') 和按钮渲染上传递一个参数,然后使用数据属性进行比较。将活动类添加为字符串。从您的状态中删除 first_click 对象。

标签: reactjs react-boilerplate


【解决方案1】:

为按钮创建一个单独的组件

class MyButton extends Component {
constructor(props){
    super(props);
    this.state = {
        person: this.props.person
    }
}

buttonActiveHandler = () => {
    let oldStatus = this.props.person.status;
    this.props.person.status = (!oldStatus ? 'active': '');
    this.setState({
        person:this.props.person
    });
}
render() {
    return (
        <button className={this.state.person.status} onClick={this.buttonActiveHandler}>{this.state.person.name}</button>
    );
}
}
export default MyButton;

然后导入按钮组件。使用 map 函数为您的代码块

<div className={classes.Box}>
     <h4>Lorem, ipsum.</h4>
    {
       this.props.survey.map((person, i) => {
         return (
            <MyButton key={i} person={person}/>
         )
      })
   }
</div>

【讨论】:

  • 嗨,@Ikram 我已经使用了你的解决方案,效果很好。但现在另一个与您的解决方案有关的问题。 (我正在尝试使用 4 天)现在在 .map 中我有多个激活的按钮和单个激活的按钮。我可以将倍数与简单的分开。但是当我单击多个按钮时,我需要添加一个类禁用简单按钮。你能帮我解决这个问题吗?非常感谢。
  • buttonActiveHandler(){ let filter = this.state.button.filterMultiple; const oldStatus = this.state.button.status; if(filter === '1'){ this.state.button.status = (!oldStatus ? 'active' : ''); } this.setState({ button: this.props.button, }); }
【解决方案2】:

解决这个问题最简单的方法是在地图中制作内容的组件,然后在那里处理该组件的状态。因此它将保持各个状态。

【讨论】:

    【解决方案3】:

    这取决于你需要什么。 您可以为具有状态的按钮创建单独的组件。

    你也可以将react state中的每个按钮的状态保持为一个数组,然后可以通过索引获取每个按钮的状态。

    我推荐第一个解决方案,管理这种状态会更容易,但从父组件获取特定按钮的状态会更难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-20
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多