Когда на самом деле рассчитывается нетронутый? Кажется, это всегда верно, даже когда форма меняется

В редукционной форме 6.4.2 у меня есть следующий код формы:

const renderUsers = ({ fields }) => {
  const table = (
    <table className={styleTable.tbody}>
      <thead className={styleTable.thead}>
        <tr>
          <th>Username</th>
          <th>Roles ('acct purch rec')</th>
        </tr>
      </thead>
      <tbody className={styleTable.tbody}>
        {fields.map((userFieldName /* , index */) => (
          <tr key={userFieldName}>
            <td>
              <Field name={`${userFieldName}.username`} component="input" disabled />
            </td>
            <td>
              <Field name={`${userFieldName}.roles`} component="input" />
            </td>
          </tr>
        ))}
      </tbody>
    </table>
  );

  return table;
};

class Form extends Component {
  // Ignore state changes with each user update.
  shouldComponentUpdate(nextProps) {
    return JSON.stringify(this.props.initialValues) !==
           JSON.stringify(nextProps.initialValues);
  }

  render() {
    const { loadUsers, handleSubmit, pristine, reset, submitting, invalid } = this.props;
console.log(pristine, invalid, submitting);
    return (
      <form onSubmit={handleSubmit}>

        <Field name="filter"
          component={TextField}
          props={{ floatingLabelText: 'Starting username', autoFocus: true }}
        />
        <RaisedButton label="Filter"
          disabled={submitting}
          className={style.button}
          onClick={() => loadUsers()}
          secondary
        />
        <br />
        <br />

        <FieldArray name="users" component={renderUsers} />
        <br />

        <div>
          <RaisedButton label={submitting ? 'Changing...' : 'Change'}
            disabled={pristine || invalid || submitting}
            className={style.button}
            type="submit"
            primary
          />
          <RaisedButton label="Clear Values"
            disabled={pristine || submitting}
            className={style.button}
            onTouchTap={reset}
            secondary
          />
        </div>

      </form>
    );
  }
}

Form.propTypes = {
  initialValues: PropTypes.object.isRequired,
  loadUsers: PropTypes.func.isRequired,
  onSubmit: PropTypes.func.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  pristine: PropTypes.bool.isRequired,
  invalid: PropTypes.bool.isRequired,
  reset: PropTypes.func.isRequired,
  submitting: PropTypes.bool.isRequired,
};

Я испытываю две проблемы:

  1. оператор console.log выводит true false false каждый раз, когда выводит что-либо. Я ожидал бы этого только при первом выводе, когда страница загружается впервые.
  2. оператор console.log выводит что-то только в этих точках:

    1. page load
    2. сосредоточиться на поле роли пользователя
    3. введите в поле фильтра
    4. нажмите кнопку фильтра

    но он ничего не выводит в этих точках:

    1. введите в поле роли пользователя
    2. размыть поле роли пользователя

Из Redux DevTools я вижу, что состояние обновляется должным образом. Например, когда я впервые нажимаю клавишу в поле роли пользователя, разница в состоянии редукции выглядит так:

redux state diff -- Извините за картинку, при копировании текста ничего не форматируется.

В частности, ввод в поле роли пользователя (или, по крайней мере, после размытия) должен был вызвать рендеринг, а затем первоначальный должен быть ложным, чтобы форма работала. Поскольку ни одна из этих вещей не происходит, кнопка отправки формы остается неактивной.

Я задаю оба этих вопроса только в том случае, если есть одна простая причина, создающая обе эти подпроблемы. Основная проблема заключается в том, что кнопка отправки всегда отключена, эти дополнительные проблемы - это то, что мне удалось выяснить.


person Kev    schedule 05.01.2017    source источник


Ответы (1)


Pristine рассчитывается как deepEqual(currentValues, initialValues) при каждом изменении значения.

Ваша проблема в том, что вы явно игнорируете пользовательские изменения с вашим shouldComponentUpdate(). Удалите это, и это сработает.

person Erik R.    schedule 05.01.2017
comment
Это исправило это! (Я все еще немного сбит с толку тем, почему shouldComponentUpdate() не улавливает изменения, поскольку, похоже, он делает что-то похожее на то, что я ожидал от deepEqual(), но это уже другая история.) Спасибо! :) - person Kev; 05.01.2017
comment
Если вы явно говорите этому компоненту не обновлять (т. е. возвращать false из shouldComponentUpdate, он не может получить только что обновленный pristine prop. - person Erik R.; 06.01.2017
comment
Однако не должен ли он возвращать true, поскольку два операнда не равны после изменения состояния? - person Kev; 06.01.2017