【问题标题】:Call a callback each time state changes in React [duplicate]每次 React 中的状态更改时调用回调 [重复]
【发布时间】:2017-11-04 09:50:09
【问题描述】:

我有一个类似的应用:

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,但我需要在每次selected_app_id 更改时调用setRoles()。我试着把它扔到 onClick 中:

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

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

 componentDidUpdate() {
       this.updateApplicationData();
 }

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

【问题讨论】:

  • 这很有用但不相关。每次我的状态发生变化时,我都需要调用回调。加载功能仅在安装组件时运行一次,我遇到的问题是用户单击按钮时
  • 啊,我明白了,你是对的
  • 为什么不将你想要的 id 作为参数传递给setRoles

标签: javascript reactjs


【解决方案1】:
  updateSelectedApp(id) {
      this.setState({selected_app_id: id}, () => {
          this.setRoles();
      });
  }

【讨论】:

  • 这不是很好。你有你想要的 id,你不需要等待状态更新只是为了得到你已经拥有的 id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2021-05-08
  • 2020-12-21
  • 1970-01-01
  • 2020-10-20
  • 2020-02-21
  • 2019-11-10
相关资源
最近更新 更多