每次React

时间:2017-06-02 22:15:16

标签: javascript reactjs

我有一个类似的应用程序:

Main.js -

import React, { Component } from 'react';
import _ from 'underscore';

import { pick_attributes } from '../utils/general';
import ApplicationsButtons from '../components/ApplicationsButtons';
import Roles from '../components/Roles';


let applications_url = 'http://127.0.0.1:8889/api/applications'


export default class Main extends Component {

  constructor(props) {
      super(props);
      this.state = {
          applications: [],
          selected_app_id: 1,
          roles: []
      };
      this.updateSelectedApp = this.updateSelectedApp.bind(this);
      this.updateApplicationData = this.updateApplicationData.bind(this);
      this.loadAppData = this.loadAppData.bind(this);
      this.getSelectedApplicationData = this.getSelectedApplicationData.bind(this);
      this.setRoles = this.setRoles.bind(this);
  }

  componentDidMount() {
    this.loadAppData();
  }

  // componentDidUpdate() {
  //     this.updateApplicationData();
  // }

  updateApplicationData() {
       this.setRoles();
  }

  loadAppData() {
      let self = this;
      $.ajax({
          url: applications_url,
          method: 'GET',
          success: function(data) {
              let objects = data.objects;
              self.setState({applications_data: objects});
              let apps_data = pick_attributes(objects, 'name', 'id');
              self.setState({applications: apps_data});

              self.updateApplicationData();
          }
      });
  }

  getSelectedApplicationData() {
      let selected_app_id = this.state.selected_app_id;
      let objects = this.state.applications_data;
      for (let i = 0; i < objects.length; i++) {
          let object = objects[i];
          if (object.id == selected_app_id) {
              return object
          }
      }
  }

  setRoles() {
      let selected_app_id = this.state.selected_app_id;
      let selected_app_object = this.getSelectedApplicationData();
      let roles_data = selected_app_object.role_list;
      let roles = pick_attributes(roles_data, 'name', 'id');
      this.setState({roles});
  }

  updateSelectedApp(id) {
      this.setState({selected_app_id: id});
  }

  render() {

    return (
      <div>
        {this.state.selected_app_id}
        <ApplicationsButtons
          apps={this.state.applications}
          clickHandler={this.updateSelectedApp}/>
        <Roles roles={this.state.roles} />
      </div>
    );
  }
}

ApplicationsButtons.js -

import React, { Component } from 'react';


export default class ApplicationsButtons extends Component {

  render() {
    var buttons = null;
    let apps = this.props.apps;
    let clickHandler = this.props.clickHandler;
    if (apps.length > 0) {
        buttons = apps.map(function(app) {
            return (
                <button
                  onClick={() => clickHandler(app.id)}
                  key={app.id}>
                    {app.name} - {app.id}
                </button>
            );
        });
    }

    return (
      <div>
        {buttons}
      </div>
    );
  }
}

Roles.js -

import React, { Component } from 'react';


export default class Roles extends Component {

  render() {
    var roles_li_elements = null;
    let roles = this.props.roles;
    console.log(roles);
    if (roles.length > 0) {
        roles_li_elements = roles.map(function(role) {
            console.log(role);
            return (
                <li key={role.id}>
                    {role.name}
                </li>
            );
        });
    }

    return (
      <div>
        <h4>Roles:</h4>
            <ul>
                {roles_li_elements}
            </ul>
      </div>
    );
  }
}

我希望在用户点击选择新应用的按钮时更新角色。现在,点击按钮会更新state.selected_app_id,但每次setRoles()更改时我都需要调用selected_app_id。我试着把它扔进onClick:

 updateSelectedApp(id) {
      this.setState({selected_app_id: id});
      this.setRoles();
  }

出于某种原因,仅在点击每个按钮两次后才更改了角色。

 componentDidUpdate() {
       this.updateApplicationData();
 }

导致状态在无限循环中永远更新。您不应该更新componentWillUpdate中的状态。

1 个答案:

答案 0 :(得分:0)

  updateSelectedApp(id) {
      this.setState({selected_app_id: id}, () => {
          this.setRoles();
      });
  }