2017-06-02 48 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