最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React hook: how to use callback in setState - Stack Overflow

programmeradmin0浏览0评论

setDropzoneFiles is done, then I need to execute setDropzoneIsLoading. In react class, I can assign callback to setState(), how do I achieve the same with the following code?

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;

setDropzoneFiles is done, then I need to execute setDropzoneIsLoading. In react class, I can assign callback to setState(), how do I achieve the same with the following code?

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;
Share Improve this question asked Sep 21, 2019 at 2:02 kenpeterkenpeter 8,30415 gold badges75 silver badges105 bronze badges 2
  • Callabck in setState hook is removed, instead you need to use useEffect with dependency array and initial state condition. – ravibagul91 Commented Sep 21, 2019 at 2:48
  • Have you considered to use useEffect instead for the loading effect instead of setDropzoneIsLoading(true)? – Koala Yeung Commented Sep 21, 2019 at 3:42
Add a ment  | 

2 Answers 2

Reset to default 4

The answers you will find online will point you to using useEffect, but this is simply a coverup for a bigger underlying issue.

As mentioned in this post by Lenz Weber as to why there is no callback in useState():

Because it invokes a thought pattern that may very well be an antipattern with hooks.

With hooks, you are writing code more declarative than imparative.

I remend reading the whole thread as there is great insight in the discussion.

What to do instead?

If you use Redux's useReducer and dispatch: through a Reducer, you can, in one operation, set the dropZoneFiles and isLoading to true without being interrupted in the middle.

A lot of folks are not fond of Redux, but it exists precisely for this kind of situation.

Also, Dan Abramov from Facebook (big promoter of hooks) himself has frequently mentioned (here for example) that not every ponent should be immediately migrated to hooks, especially because best-practices need to solidify; I myself prefer Class Components when dealing with plex ponents.

You can use the useEffect hook:

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;
发布评论

评论列表(0)

  1. 暂无评论