功能性Reactjs组件中的Redux-Form-mapStateToProps使用以前的道具

时间:2020-04-15 09:54:32

标签: reactjs react-redux redux-form

我现在在这里坐了几个小时,找不到解决方案。在下面,您将看到功能性的React组件,该组件与Redux和Redux-Form结合在一起。该组件具有可选的道具“注释”。

现在是我的问题:当我首先调用带有以下注释的组件

<NoteForm note={...}></NoteForm>

一切都很好-mapStateToProps从ownProps中提取注释,并将值注入初始值。

但是,如果我将此组件称为而没有之后,则将其称为,带有如下注释

<NoteForm></NoteForm>

ownProps突然仍然包含来自先前渲染的笔记。如果以前提供了注释,则该组件似乎不接受“未定义”作为更改新生命周期中的道具的触发器。

有人知道吗?

请在下面找到整个组件

import React, { FC, useCallback, useState } from 'react';
...

interface RFInProps {
  closeForm: () => void;
  note?: ListNote;
  saveNote: (title: string, content: string, shareWithSubject: boolean) => Promise<ThunkAnyAction<ListNote>>;
}

type OwnProps = RFInProps & InjectedFormProps<UpdateNoteFormValues, RFInProps>

const NoteForm: FC<OwnProps> = (props) => {
  const [t] = useTranslation();
  const formHeadline = props.note ? 'x.notes.edit' : 'x.notes.new';
  const [errors, setErrors] = useState<Record<string, NoteAPIError[]>>({});

  ...

  const renderInput = useCallback(({ input, label, type, meta: { error, touched } }: FieldType) => (
    <CustomFormInput
      { ...input }
      label={ label }
      labelKey={ label }
      type={ type }
      error={ touched ? error : undefined }
    />
  ), [props.note]);

  const renderTextarea = useCallback(
    ({ input, translationKey, label, meta: { error, touched } }: FieldType) => (
      <CustomTextArea
        { ...input }
        translationKey={ translationKey }
        error={ touched ? error : null }
        label={ label }
        labelKey="x.notes.content"
        minHeight={ 60 }
        autoExpand
      />
    ),
    [props.note],
  );

  const renderCheckBox = useCallback(
    ({ input, label }) => (
      <CheckBox
        { ...input }
        label={ label }
      />
    ),
    [props.note],
  );

  const renderValidationError = (field: string, err: NoteAPIError) => (
    <div>
      { field }:
      { t('x.error.' + err.type) }
      { err.args && ' (' + Object.keys(err.args)
        .map((argKey) => `${ t(`x.error.${ argKey }`) }: ${ err.args[ argKey ] }`)
        .join(', ') + ')'
      }
    </div>
  );

  return (
    <NoteFormContainer>
      <form onSubmit={ props.handleSubmit(submit) } noValidate>
          ...
          <Field
            name="content"
            label={ t('x.notes.content') }
            component={ renderTextarea }
            validate={ [validatorRequired] }
          />
        ...
      </form>
    </NoteFormContainer>
  );
};

const mapStateToProps = (_: StoreI, ownProps: RFInProps) => ( {
  initialValues: {
    title: ownProps.note ? ownProps.note.title : '',
    content: ownProps.note ? ownProps.note.content : '',
    share_with_subject: ownProps.note ? ownProps.note.share_with_subject : false,
  },
} );

// Ignore because reduxForm accepts a second argument indeed
const NoteFormRF = connect(mapStateToProps, null)(reduxForm<UpdateNoteFormValues, RFInProps>({
  form: 'noteForm',
  destroyOnUnmount: true,
  forceUnregisterOnUnmount: true,
})(NoteForm));
export default NoteFormRF;

0 个答案:

没有答案