价值状态未更新

时间:2017-05-27 01:37:19

标签: javascript reactjs

我有一张表,每行有一个输入框。总共有3行,我需要从这三个输入框值中计算总数。但价值状态没有更新。我只获得了初始的价值状态。例如,有一个agent,hotel,admin的状态对象。如果我初始化代理值10,我在输入框中得到10,但当我尝试更改值时,我只得到10.该值不会更新。

这是代码

const Tbody = ({ roles, states, onChange, onBlur }) => {
  const row = roles.map((role, index) => (
    <tr key={index}>
      <td>{index + 1}</td>
      <td>{role.label}</td>
      <td>
        <TextFieldGroup
          id="formControlsText"
          type="number"
          name={role.name}
          value={states[role.name]}
          onChange={event => onChange(event)}
          onBlur={event => onBlur(event)}
          error={states.errors[role.name]}
          required
        />
      </td>
    </tr>
  ));
  return <tbody>{row}</tbody>;
};

class Commission extends React.PureComponent {
  state = {
    agentCommission: 0,
    hotelCommission: 0,
    adminCommission: 0,
    errors: {},
    isSubmitted: false
  };

  handleChange = event => {
    console.log(event.target);
    const fieldName = event.target.name;
    this.setState(
      { [event.target.name]: parseFloat(event.target.value) },
      () => {
        this.validateField([fieldName]);
      }
    );
  };

  handleBlur = event => {
    const fieldName = event.target.name;
    this.validateField([fieldName]);
  };

  validateField = validate => {
    const errors = { ...this.state.errors };
    let hasError = false;
    validate.forEach(field => {
      if (
        parseFloat(this.state[field]) > 100 ||
        parseFloat(this.state[field]) < 0
      ) {
        hasError = true;
        errors[field] = 'cannot be less than 0 and more than 100';
      } else {
        errors[field] = '';
      }
    });
    this.setState({ errors });
    return !hasError;
  };

  render() {
    const { agentCommission, adminCommission, hotelcommission } = this.state;
    const totalCommission = agentCommission + adminCommission + hotelcommission;
    console.log('totalCommission', totalCommission);
    return (
      <div className="table-responsive">
        <table className="table table-striped table-bordered table-condensed">
          <thead>
            <tr>
              <th>S.N</th>
              <th>Role</th>
              <th>Commission</th>
            </tr>
          </thead>
          <Tbody
            roles={[
              { name: 'agentCommission', label: 'Agent' },
              { name: 'hotelCommission', label: 'Hotel Owner' },
              { name: 'adminCommission', label: 'Admin' }
            ]}
            states={{ ...this.state }}
            onChange={this.handleChange}
            onBlur={this.handleBlur}
          />
          <tbody>
            <tr>
              <td>
                <button
                  className="btn btn-primary"
                  onClick={this.handleSubmit}
                  disabled={totalCommission === 100 ? false : true}>
                  Save Changes
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:1)

在ReactJS中,当您扩展React组件类时,必须在构造函数中初始化状态。此外,您需要调用父类&#39;构造函数通过super(props)。这是React库的类可以访问您的状态值以及提供setState()

等方法访问的唯一方法

https://codepen.io/julianfresco/pen/ybrZNe/

class Commission extends React.PureComponent {

  constructor(props, context) {
    super(props)
    this.state = {
      agentCommission: 0,
      hotelCommission: 0,
      adminCommission: 0,
      errors: {},
      isSubmitted: false
    };

    // method instance bindings
    this.handleChange = this.handleChange.bind(this)
    this.handleBlur = this.handleBlur.bind(this)
    this.validateField = this.validateField.bind(this)
  }

  // ...

  // you had 1 typo in the render function, hotelCommission wasn't camel case
  render() {
    const { agentCommission, adminCommission, hotelCommission } = this.state;
    // ...
  }
}

答案 1 :(得分:0)

问题是Commission类,您没有初始化状态。 您的代码应如下所示:

const Tbody = ({ roles, states, onChange, onBlur }) => {
  const row = roles.map((role, index) => (
    <tr key={index}>
      <td>{index + 1}</td>
      <td>{role.label}</td>
      <td>
        <input
          id="formControlsText"
          type="number"
          name={role.name}
          value={states[role.name]}
          onChange={event => onChange(event)}
          onBlur={event => onBlur(event)}
          error={states.errors[role.name]}
          required
        />
      </td>
    </tr>
  ));
  return <tbody>{row}</tbody>;
};

class Commission extends React.PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      agentCommission: 0,
      hotelCommission: 0,
      adminCommission: 0,
      errors: {},
      isSubmitted: false
    };  
  }


  handleChange(event)  {
    console.log(event.target);
    const fieldName = event.target.name;
    this.setState(
      { [event.target.name]: parseFloat(event.target.value) },
      () => {
        this.validateField([fieldName]);
      }
    );
  };

  handleBlur(event) {
    const fieldName = event.target.name;
    this.validateField([fieldName]);
  };

  validateField(validate) {
    const errors = { ...this.state.errors };
    let hasError = false;
    validate.forEach(field => {
      if (
        parseFloat(this.state[field]) > 100 ||
        parseFloat(this.state[field]) < 0
      ) {
        hasError = true;
        errors[field] = 'cannot be less than 0 and more than 100';
      } else {
        errors[field] = '';
      }
    });
    this.setState({ errors });
    return !hasError;
  };

  render() {
    const { agentCommission, adminCommission, hotelcommission } = this.state;
    const totalCommission = agentCommission + adminCommission + hotelcommission;
    console.log('totalCommission', totalCommission);
    return (
      <div className="table-responsive">
        <table className="table table-striped table-bordered table-condensed">
          <thead>
            <tr>
              <th>S.N</th>
              <th>Role</th>
              <th>Commission</th>
            </tr>
          </thead>
          <Tbody
            roles={[
              { name: 'agentCommission', label: 'Agent' },
              { name: 'hotelCommission', label: 'Hotel Owner' },
              { name: 'adminCommission', label: 'Admin' }
            ]}
            states={{ ...this.state }}
            onChange={this.handleChange}
            onBlur={this.handleBlur}
          />
          <tbody>
            <tr>
              <td>
                <button
                  className="btn btn-primary"
                  onClick={this.handleSubmit}
                  disabled={totalCommission === 100 ? false : true}>
                  Save Changes
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    );
  }
}

小提琴演示:https://codesandbox.io/s/KO3vDRGjR