奇怪的React挂钩行为,无法从函数访问新状态

时间:2019-05-08 16:33:16

标签: reactjs modal-dialog antd react-hooks

我使用库react-use-modal,并且 我正在尝试在confirmLoading函数中读取handleClick的更新值。

handleClick确实读取了confirmLoading时定义的const [ confirmLoading, setConfirmLoading ] = useState(false)的第一个值,但是当我setConfirmLoading内的handleOk时从不更新。

我不明白自己在做什么错

import { Button, Modal as ModalAntd } from 'antd'
import { useModal } from 'react-use-modal'

export interface ModalFormProps {
    form: React.ReactElement
}

export const ModalForm: React.FC = () => {
    const [ confirmLoading, setConfirmLoading ] = useState(false)
    const { showModal, closeModal } = useModal()

    const handleOk = () => {
        setConfirmLoading(true)
        setTimeout(() => {
            setConfirmLoading(false)
            closeModal()
        }, 1000)
    }

    const handleCancel = () => {
        closeModal()
    }

    const handleClick = () => {             
        showModal(({ show }) => (
            <ModalAntd                  
                onCancel={handleCancel}
                onOk={handleOk}
                title='Title'
                visible={show}
            >
                //  the value of confirmLoading is always the one defined 
                //  with useState at the beginning of the file.
                <p>{confirmLoading ? 'yes' : 'no'}</p>                  
            </ModalAntd>
        ))
    }

    return (
        <div>
            <Button onClick={handleClick}>
                Open Modal
            </Button>
        </div>
    )
}

1 个答案:

答案 0 :(得分:3)

这是由于关闭而发生的。传递给showModal的组件会记住confirmLoading,当您调用函数setConfirmLoading时,组件将再次呈现,并重新创建函数handleClickhandleClick中的'Old'showModal和'old'组件对confirmLoading中的新值一无所知。

尝试执行以下操作:

export const ModalForm: React.FC = () => {
    const { showModal, closeModal } = useModal();

    const handleClick = () => {

        showModal(({ show }) => {
            const [ confirmLoading, setConfirmLoading ] = useState(false);
            const handleOk = () => {
                setConfirmLoading(true)
                setTimeout(() => {
                    setConfirmLoading(false)
                    closeModal()
                }, 1000)
            };

            const handleCancel = () => {
                closeModal()
            };

            return (
                <ModalAntd
                    onCancel={handleCancel}
                    onOk={handleOk}
                    title='Title'
                    visible={show}
                >
                    // the value of confirmLoading is always the one defined
                    // with useState at the beginning of the file.
                    <p>{confirmLoading ? 'yes' : 'no'}</p>
                </ModalAntd>
            );
        })
    };

    return (
        <div>
            <Button onClick={handleClick}>
                Open Modal
            </Button>
        </div>
    )
}