简体   繁体   中英

Unable to set dynamic state from render method react es6

I am trying to add dynamic states from a method. The idea is when i call the method from a render method it would accept the parameter value to set dynamic state values.

Here is my code:

renderFeaturePermissionOptions( featureName ) {
  // Generate permission rules.
  let viewPermission    = featureName + "_view"
  let createPermission  = featureName + "_create"
  let editPermission    = featureName + "_edit"
  let deletePermission  = featureName + "_delete"
  // Set states for all dynamic checkboxes.
  this.setState( { [viewPermission]   : true } )
  this.setState( { [createPermission] : true } )
  this.setState( { [editPermission]   : true } )
  this.setState( { [deletePermission] : true } )
  return(
    <tr>
      <td>{featureName}</td>
      <td><input name={ featureName + "/selectAll" } type="checkbox" onChange={this.checkSiblingCheckBoxes}/></td>
      <td><input name={ featureName + "/view" } type="checkbox"/></td>
      <td><input name={ featureName + "/create" } type="checkbox"/></td>
      <td><input name={ featureName + "/edit" } type="checkbox"/></td>
      <td><input name={ featureName + "/delete" } type="checkbox"/></td>
    </tr>
  )
}

I want to refactor this code so that i can call this method for any route name given in the parameter and it will create the states as the parameter name.

Though it is not completed, but when i call this method from the render method like this

{ this.renderFeaturePermissionOptions( 'Organization' ) }

it takes an infinite loop and generates this error:

在此处输入图片说明

How i can set this states here which are coming from the parameter of renderFeaturePermissionOptions( 'Contact' ) ? -> An example call.

you cannot call setState in your render function, when you call setState, the component will render again, if you call it in render function. it will be endless loop.

so you can try to write it as another childComponent, maybe it can look like this.

const trComponent = ({name, onChange}) => {
   return (
        <tr>
          <td>{name}</td>
          <td><input name={ name + "/selectAll" } type="checkbox" onChange={onChange}/></td>
          <td><input name={ name + "/view" } type="checkbox"/></td>
          <td><input name={ name + "/create" } type="checkbox"/></td>
          <td><input name={ name + "/edit" } type="checkbox"/></td>
          <td><input name={ name + "/delete" } type="checkbox"/></td>
        </tr>
   );
}

// if you want to set dynamic state, you can set it in this way
class trComponent extends Component {
    constructor (props) {
        let viewPermission    = props.name + "_view"
       let createPermission  = props.name + "_create"
       let editPermission    = props.name + "_edit"
       let deletePermission  = props.name + "_delete"
        this.state = {
            [viewPermission]: true,
            ....
        }
    }

    render () {
        return (
        <tr>
          <td>{name}</td>
          <td><input name={ this.props.name + "/selectAll" } type="checkbox" onChange={this.props.onChange}/></td>
          <td><input name={ this.props.name + "/view" } type="checkbox"/></td>
          <td><input name={ this.props.name + "/create" } type="checkbox"/></td>
          <td><input name={ this.props.name + "/edit" } type="checkbox"/></td>
          <td><input name={ this.props.name + "/delete" } type="checkbox"/></td>
        </tr>
   );
    }
}

// then use it in this way

<trComponent name='Organization' onChange={this. checkSiblingCheckBoxes}/>

You should not set state in render method or methods which are getting called when rendering happens.

This is incorrect in your code.

  // Set states for all dynamic checkboxes.
  this.setState( { [viewPermission]   : true } )
  this.setState( { [createPermission] : true } )
  this.setState( { [editPermission]   : true } )
  this.setState( { [deletePermission] : true } )

Set state in some lifecycle methods or on some user action on your component.

Edit: Yes initialize your default state in your component's constructor

export default class TestComp extends Component {

    constructor(props) {
        super(props);
        this.state = {
            viewPermission : true,
            createPermission] : true,
            editPermission]   : true,
            deletePermission] : true

        };
    }
 // Rest of your component methods such as render and others

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM