2017-06-02 47 views
0

我有一个应用程序,如:调用回调在每次状态变化作出反应

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

我希望角色在使用时更新r点击一个按钮,选择一个新的应用程序。现在,单击按钮确实会更新state.selected_app_id,但我需要每次调用selected_app_id时调用setRoles()。我试图把它扔在onclick:

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

出于某种原因,只有两次单击每个按钮后更改了角色。

componentDidUpdate() { 
     this.updateApplicationData(); 
} 

导致状态在无限循环中永久更新。你不应该更新componentWillUpdate内部的状态。

+0

这是有用的,但没有关系的。我需要每次某一件事调用回调在我的状态变化。负载功能只运行一次,当组件安装,我的问题是,当用户点击按钮 – codyc4321

+0

我明白了,你是对的 – codyc4321

+0

为什么不通过你想要的ID作为参数传递给'setRoles'? – azium

回答

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

这并不好。您想要在那里的ID,你并不需要等待状态更新只是为了让您已有的ID – azium