【问题标题】:Strange React hooks behavior, can't access new state from a function奇怪的 React 挂钩行为,无法从函数访问新状态
【发布时间】:2019-05-08 16:33:15
【问题描述】:

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

handleClick 确实读取了confirmLoading 在执行const [ confirmLoading, setConfirmLoading ] = useState(false) 时定义的第一个值,但当我在handleOksetConfirmLoading 时永远不会更新。

我不明白我做错了什么

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>
    )
}

【问题讨论】:

    标签: reactjs modal-dialog antd react-hooks


    【解决方案1】:

    这是由于关闭而发生的。您传递给showModal 的组件会记住confirmLoading,并且当您调用函数setConfirmLoading 时,您的组件会再次呈现并重新创建函数handleClickshowModal 中的“旧”handleClick 和“旧”组件对 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>
        )
    }
    
    
    

    【讨论】:

    • 谢谢安德烈。我知道由于closures 而发生了一些事情,但是每次我修改代码时,我最终都会以错误的方式使用hooks,并带有you can't use hooks there 消息。您的解决方案完美运行!
    猜你喜欢
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 2021-03-22
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多