如何使用自定义挂钩中已更新的状态来更新父组件?

时间:2020-05-07 01:25:32

标签: reactjs react-hooks

我不确定是否曾经问过这个问题。谷歌搜索后找不到任何东西。

我有一个父组件,基本上有一个按钮,单击该按钮将打开一个模态。

在模式内部,有一种形式可以对API进行后期调用。如果呼叫后成功,则需要关闭模式。我正在尝试使用自定义钩子来实现此目的。

下面是我的代码:

自定义挂钩

type savedHook = {
    saved: boolean,
    loading: boolean,
    error: string,
    saveSearch: (search: any) => void,
    showNewModal: boolean,
    setShowNewModal: (boolean) => void
};

export const useSaveSearch = () : savedSearchHook => {
    const [loading, setLoading] = useState(false);
    const [saved, setSaved] = useState(false);
    const [error, setError] = useState('');
    const [showNewSaveSearch, setNewShowSearch] = useState(false);

    const saveSearch = async (search: any) => {
        setLoading(true);

        fetch('my api', {
            method: 'POST',
            body: JSON.stringify(search),
            headers: {
                'Content-Type': 'application/json'
            }
        }).then((data) => {
            setSaved(true);
            setLoading(false);
            setShowNewModal(false);
        }).catch((error) => {
            setError(error);
            setLoading(false);
        });
    }

    const setShowNewModal = (show: boolean) => {
        setNewShowSearch(show);
    }


    return {
        error,
        loading,
        saveSearch,
        saved,
        setShowNewModal,
        showNewModal: showNewSaveSearch
    }

}

模式

export default function SaveSearch({isOpen, onDismiss}) {
    const { state } = useSearch();
    const [name, setName] = useState('');
    const { loading, saved, error, saveSearch } = useSaveSearch();

    const handleSave = () => {
        saveSearch({
            name,
            query: state.query,
            type: state.type
        });
    }

    return (
      <Modal isOpen={isOpen} onDismiss={onDismiss}>
        <div>
          <span>Save Search ({state.type})</span>
          <IconButton styles={iconButtonStyles} iconProps={{iconName: 'Cancel'}} onClick={onDismiss} />
        </div>
        <div>
              <TextField label="Name" autoFocus value={name} onChange={(e, value) => setName(value)} />
                {loading && <Spinner size={SpinnerSize.small} />}
              <DefaultButton text="Save" onClick={handleSave} iconProps={{iconName: 'Save'}} disabled={name.length === 0 || loading} />


        </div>

      </Modal>
    )
  }

父组件

export default function ParentComponent() {
   const { showNewModal, setShowNewModal } = useSaveSearch();

   return (
     <div>
       {<SaveSearch isOpen={showNewModal} onDismiss={() => setShowNewModal(false)} />}
        <PrimaryButton text="Save Search" onClick={() => setShowNewModal(true)} iconProps={{iconName: 'Save'}} />
    </div>
   );
}

我面临的问题是,要打开模式,我要从正常工作的父组件中调用setShowNewModal。但是在保存功能之后,我从挂钩中调用setShowNewModal,而挂钩在父组件中没有更新。

1 个答案:

答案 0 :(得分:1)

如果您能提供一个可行的示例,那就太好了。

无论如何,如果我是对的,setShowNewModal(false);自定义钩子的saveSearch方法内的useSaveSearch应该关闭Modal,对吗?
好吧,如果是这样,您可以在setShowNewModal内部调用setNewShowSearch。然后,当您编写以下行时,将为名为setNewShowSearch的属性返回showNewModal的值,但在Modal内部:

const { loading, saved, error, saveSearch } = useSaveSearch();

在解构函数中,您不考虑showNewModal属性。也许我在流程中遗漏了一些东西:这就是为什么我要求一个可行的演示。

无论如何,回到问题所在:在Modal组件内部,您只需传递onDismiss方法:

const { loading, saved, error, saveSearch } = useSaveSearch(onDismiss);

useSaveSearch自定义钩子内,只需调用onDismiss参数,该参数将调用() => setShowNewModal(false)组件中定义的回调Parent