首页 > 解决方案 > FormSpy-订阅脏的onChange未在输入字段中显示值

问题描述

我们正在使用 FormSpy,订阅脏。当dirty为true时,FormSpy中的OnChange函数将更新redux中的dirty标签。当我输入任何输入字段时,第一个字母不会显示,但 redux 状态会dirty:true在第一个字母笔划时更新。

表单也使用不同的文件写入

<Form
 component={Theform}
/>

这就是我们使用 FormSpy 的方式

<FormSpy
  subscription={{ dirty: true }}
  onChange={state => this.updateDirty(state.dirty)}
  {...props}
/>

updateDirty(isDirty) {
  const { toggleIsDirty, dirtyState } = this.props;
  if (isDirty) {
    if (!dirtyState.isDirty) {
      toggleIsDirty();
    }
  }
}

if (isDirty)检查未完成时,它会不断更新存储值,但不会在输入字段中显示任何内容。我们哪里出了问题?

更新:我无法复制粘贴实际代码,但它是这样的。

动作.js

const toggleDirty = () => ({
  type: types.TOGGLE_DIRTY,
});

export { toggleDirty };

减速器.js

const dirtyState = (state = { isDirty: false}, { type }) => {
  switch (type) {
    case types.TOGGLE__DIRTY: {
      return {
        isDirty: !state.isDirty,
      };
    }
    default: return state;
  }
};

模态的.jsx

class Modal extends Component {
  render () {
    const {storeValues} = this.props;
    const initialValues = {
      field1: storeValue.field1,
      field2: storeValue.field2
    }

    return {
      <Form 
        id="detailsForm"
        initialValues={initialValues}
        component={DetailsForm}
      />
    }
  }
}
const mapStateToProps = ({ storeValues }) => ({
  storeValues,
});

export default connect(mapStateToProps, null)(Modal);

详细信息Form.jsx

class DetailsForm extends Component {
  constructor(props) {
    super(props);
    this.updateDirty = this.updateDirty.bind(this);
  }
  updateDirty(isDirty) {
    const { toggleIsDirty, dirtyState } = this.props;
    if (isDirty && !dirtyState.isDirty) {
      toggleIsDirty();
    }
  }

  render() {
    const {updateDirty} = this;
    const {
      intl, submitError, submitErrors, submitFailed, dirty, handleSubmit, form, errors, values, ...props
    } = this.props;
    return{
      <form onSubmit={handleSubmit} className="benefit-form">
        <FormSpy
          subscription={{ dirty: true }}
          onChange={state => updateDirty(state.dirty)}
          {...props}
        />
        <React.Fragment>
          <Input .... />
        </React.Fragment>
      </form>
    }
  }
}

const mapStateToProps = ({ dirtyState}) => ({
  dirtyState,
});

const mapDispatchToProps = dispatch => ({
  toggleIsDirty() {
    dispatch(toggleDirty());
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(DetailsForm);

当我在输入中输入“123”之类的内容时,只显示“23”。当我输入第一个数字时,它只会isDirty在商店中将标志变为真。在调试时,我发现 updateDirty 为输入的第一个字符调用了两次——一次isDirty为真,一次为假。

我在 FormSpy 的 onChange 中放置了一个控制台日志,它在初始表单加载期间被触发dirty为 false。当我输入第一个字母时,它会更新为 true,动作被调度,然后立即再次被触发为 false。然后不显示该字母。但从第二个字母开始,它表现正常。当我使用本地状态和 setState 而不是调度时,这没有任何问题。

当导航离开带有脏数据的页面时,我们使用该标志显示模式。

标签: reactjsreact-final-form

解决方案


当您的状态存储在多个位置,并且状态由未内置在 React 中的事件更新时,您将获得组件多次呈现的行为,其中的数据可能会发生冲突,例如在您的情况下肮脏的国家不同意。一旦数据变成您期望的样子,重新渲染就会停止,在您的情况下,脏状态是相同的。

选项1

仅从其中一家商店读取状态。在您的情况下,忽略最终形式传递的内容,并且只从 redux 中读取

选项 2

找到第一个非反应事件被触发的位置,并将其包装在unstable_batchedUpdate


推荐阅读