React Hook:如何在setState中使用回调

时间:2019-09-21 02:02:43

标签: javascript reactjs

setDropzoneFiles完成,然后我需要执行setDropzoneIsLoading。在react类中,我可以将回调分配给setState(),如何使用以下代码实现相同的目的?

const Dropzone = () => {

    const [dropzoneFiles, setDropzoneFiles] = useState([]);
    const [dropzoneIsLoading, setDropzoneIsLoading] = useState(false);

    const onDropAccepted = useCallback(
        acceptedFiles => {
            let someFiles = ['a', 'b'];

            // How to use callback?
            setDropzoneFiles(someFiles, () => {
                setDropzoneIsLoading(true)
            })

        }
    );


    const {getRootProps, getInputProps} = useDropzone({
        onDropAccepted,
        onDropRejected,
        multiple: true
    });
    }

export default Dropzone;

2 个答案:

答案 0 :(得分:1)

您在网上找到的答案将指向您使用useEffect,但这只是掩盖了更大的潜在问题。

this post by Lenz Weber所述,为什么useState()中没有回调:

  

因为它调用的思维模式很可能是带有钩子的反模式。

     

使用钩子,您编写的代码比声明性的更具声明性。

我建议您阅读整个主题,因为在讨论中有很多见识。

该怎么办?

如果您使用Redux的useReducer并通过Reducer调度:您可以通过一次操作将dropZoneFiles和isLoading设置为true,而不会在中间被中断。

很多人不喜欢Redux,但是正是这种情况而存在。

此外,来自Facebook(钩子的主要推动者)的Dan Abramov自己经常提到(here for example),并不是每个组件都应立即迁移到钩子,尤其是因为最佳实践需要巩固;在处理复杂的组件时,我本人更喜欢使用Class Components。

答案 1 :(得分:1)

您可以使用useEffect钩子:

const Dropzone = () => {

    const [dropzoneFiles, setDropzoneFiles] = useState([]);
    const [dropzoneIsLoading, setDropzoneIsLoading] = useState(false);

    const onDropAccepted = useCallback(
        acceptedFiles => {
            let someFiles = ['a', 'b'];

            // How to use callback?
            setDropzoneFiles(someFiles);

        }
    );

    useEffect(() => {
       if (dropzoneFiles) {
          setDropzoneIsLoading(true);
       }

    }, [dropzoneFiles])


    const {getRootProps, getInputProps} = useDropzone({
        onDropAccepted,
        onDropRejected,
        multiple: true
    });
    }

export default Dropzone;