React:如何为复选框数组设置动态状态

时间:2017-08-04 01:43:04

标签: javascript reactjs state

我有一个ServiceCard组件,它接受一个Object。此对象可能包含具有权限数组的权限密钥,每个权限都包含disabled:truedisabled:false

如何为这种用例设置基本状态?

对于Service对象,Rights Array的含义如下:

enter image description here

(刚刚意识到我错过拼写的炮塔:p)

构造函数和权限映射函数

constructor(props) {
  super(props);
  this.onChangeHandler = this.onChangeHandler.bind(this);
  this.updateService = this.updateService.bind(this);

  // How to define this.state for dynamic Rights Array?

  this.state = {
    serviceName: props.name,
    rights: props.rights
  }

  props.rights.map(right => {
    console.log(' map right', right)
    console.log(' this.state', this.state)
  })
}


// Later down in the render...
<ul>
  {
    rights.map(right =>
      <li key={ right.name }>
        <input type="checkbox"
               checked={ !right.disabled }
               onChange={ () => this.onChangeHandler(name, right) }/>
        <p>{ right.name }</p>
      </li>
    )
  }
</ul>

完整组件代码

import React, { Component } from 'react'

export default class ServiceCard extends React.Component {
  constructor(props) {
    super(props);
    this.onChangeHandler = this.onChangeHandler.bind(this);
    this.updateService = this.updateService.bind(this);
    this.deleteService = this.deleteService.bind(this);
  }

  onChangeHandler(name, right) {
    console.log('onChangeHandler...')
    console.log(' name', name)
    console.log(' right', right)

  }

  deleteService(serviceName) {
    this.props.deleteService(serviceName);
  }

  render () {
    const name = this.props.name;
    // console.log('this.props', this.props)
    const rights = this.props.rights;

    return (
      <li className="service-card-item">
        <section className="card">
          <div className="icon-connectdevelop service-icon"></div>
          <div className="service-details">
            <h3>{ name }</h3>
            <section className="rights-section">
              <ul>
                {
                  rights.map(right =>
                    <li key={ right.name }>
                      <input type="checkbox" checked={ !right.disabled } onChange={ () => this.onChangeHandler(name, right) }/>
                      <p>{ right.name }</p>
                    </li>
                  )
                }
              </ul>
              <div className="icon-cancel-circled" title="Delete Service" onClick={ () => this.deleteService(name) }></div>
            </section>
          </div>
        </section>
      </li>
    )
  }
}

1 个答案:

答案 0 :(得分:1)

正如Cloud Tseng提供的链接一样,我最初使用权限数组设置我的状态:

this.state = {
  serviceName: props.name,
  rights: props.rights
}

然后只需要获取右边的名称就可以使用它的复选框changeHandled,使用Ramda进行一些函数映射,返回一个新的权限数组,然后将权限状态设置为新更新的数组:

onChangeHandler与Ramda功能性感

onChangeHandler(name, right) {
  const serviceRights = this.state.rights;

  const findRight = R.curry((updatedRight, propsRight) => {
    if (updatedRight.name === propsRight.name) {
      propsRight.disabled = !propsRight.disabled;
    }
    return propsRight;
  });

  const updatedRights = R.map(findRight(right), serviceRights);
  console.log('  updatedRights', updatedRights)

  this.setState({
    rights: updatedRights
  }, console.log('  >>> State update completed:', this.state));
}

enter image description here

enter image description here

完全固定的代码

import React, { Component } from 'react'
import * as R from 'ramda'

export default class ServiceCard extends React.Component {
  constructor(props) {
    super(props);
    console.log('ServiceCard', props)
    this.onChangeHandler = this.onChangeHandler.bind(this);
    this.updateService = this.updateService.bind(this);
    this.deleteService = this.deleteService.bind(this);

    this.state = {
      serviceName: props.name,
      rights: props.rights
    }

    props.rights.map(right => {
      console.log(' map right', right)
      console.log(' this.state', this.state)
    });
  }

  onChangeHandler(name, right) {
    console.log('onChangeHandler...')

    const serviceRights = this.state.rights;

    const findRight = R.curry((updatedRight, propsRight) => {
      if (updatedRight.name === propsRight.name) {
        propsRight.disabled = !propsRight.disabled;
      }
      return propsRight;
    });

    const updatedRights = R.map(findRight(right), serviceRights);
    console.log('  updatedRights', updatedRights)

    this.setState({
      rights: updatedRights
    }, console.log('  >>> State update completed:', this.state));
  }

  updateService() {

  }

  deleteService(serviceName) {
    this.props.deleteService(serviceName);
  }

  render () {
    const name = this.props.name;
    // console.log('this.props', this.props)
    const rights = this.state.rights;

    return (
      <li className="service-card-item">
        <section className="card">
          <div className="icon-connectdevelop service-icon"></div>
          <div className="service-details">
            <h3>{ name }</h3>
            <section className="rights-section">
              <ul>
                {
                  rights.map(right =>
                    <li key={ right.name }>
                      {/* <input type="checkbox" checked={ !right.disabled } onChange={ () => this.onChangeHandler(name, right) }/> */}
                      <input type="checkbox" checked={ !right.disabled } onChange={ () => this.onChangeHandler(name, right) }/>
                      <p>{ right.name }</p>
                    </li>
                  )
                }
              </ul>
              <div className="icon-cancel-circled" title="Delete Service" onClick={ () => this.deleteService(name) }></div>
            </section>
          </div>
        </section>
      </li>
    )
  }
}