【问题标题】:How to modify the code such that can call usehook using react and typescript?如何修改代码以便可以使用 react 和 typescript 调用 usehook?
【发布时间】:2020-11-12 00:52:57
【问题描述】:

单击添加按钮且计数大于或小于 0 时会显示一个弹出窗口。

下面是代码,

function AddButton () {
    const [isOpen, setIsOpen] = React.useState(false);
    const count = useGetCount();
    useTrigger(isOpen, count);
    const on_add_click = ()  => {
        setIsOpen(true);
    }

    return (
        <button onClick={on_add_click}>add</button>
    );  
}


interface ContextProps {
    trigger: (count: number) => void;
}

const popupContext = React.createContext<ContextProps>({
    trigger: (count: number) => {},
});

const usePopupContext = () => React.useContext(popupContext);

export const popupContextProvider = ({ children }: any) => {
    const [show, setShow] = React.useState(false);
    const limit = 0;

    const dismiss = () => {
        if (show) {
            sessionStorage.setItem(somePopupId, 'dismissed');
            setShow(false);
        }

    };

    const isDismissed = (dialogId: string) =>
        sessionStorage.getItem(dialogId) === 'dismissed';

        const context = {
            trigger: (count: number) => {
            if (!isDismissed(somePopupId) && count <= limit) {
                setShow(true);
            } else if (count > limit) {
                setShow(false);
            }
        },
    };

    return (
        <popupContext.Provider value={context}>
            {children}
            {show && (
                <Popup onHide={dismiss} />
            )}
        </popupContext.Provider>
    );
};


export function useTrigger(enabled: boolean, count: number) {
    const { trigger } = usePopupContext();
    React.useEffect(() => {
        if (enabled) {
            trigger(count);
        }
    }, [enabled, count, trigger]);
}

这可行,但仅在启用为 true 时才调用触发方法。

我想修改上面的代码,这样当用户点击添加按钮时,我希望这个 useTrigger 发生。我不想检查启用和调用触发器。

我尝试了以下已启用的删除检查。

export function useTrigger(enabled: boolean, count: number) {
    const { trigger } = usePopupContext();
    React.useEffect(() => {
        trigger(count);
    }, [enabled, count, trigger]);
}

这可行,但弹出窗口显示为计数小于或等于 0。但我希望它首先检查是否单击了添加按钮。

在用户单击 on_add_click 中的添加按钮后不久,我希望显示弹出窗口。 如何修改上面的代码?我是使用钩子的新手。有人可以帮我解决这个问题吗?谢谢。

编辑:强文本 我试图做类似下面的事情,但我得到了错误

未捕获的不变违规:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。

on_add_click = () => {
    Trigger(count);
}

export function Trigger(count: number) {
    const { trigger } = usePopupContext();
    React.useEffect(() => {
        trigger(count);
    }, [count, trigger]);
}

我该如何解决这个问题。

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    如果我没听错,你只需要在你的钩子中添加一个状态并返回 setter 来调用它 onclick:

    export function useTrigger(count: number) {
        const [clicked, setClicked] = React.useState(false)
        const { trigger } = usePopupContext();
        React.useEffect(() => {
            if(clicked) {
                trigger(count);
            }
     
        }, [count, trigger, clicked]);
        const clickCb = useCallback(() => {setClicked(true)}, [])
        return cb
    }
    

    然后在带有按钮的组件中执行以下操作:

    const Component = (props) => {
        const onClick = useTrigger(props.count)
        /* ... */
        return <button onClick={onClick}/>
    }
    

    【讨论】:

    • 感谢这几乎可以工作。但是当用户单击将他重定向到主页(history.push (/home))的按钮时,单击状态设置为 false。它不会在 useEffect 中调用触发方法。此弹出窗口在所有页面中都可见,因此重定向到主页点击按钮仍应保持点击状态为真。你能帮我解决这个问题吗?谢谢。
    • 我明白了。我认为对您来说最好的方法是将clicked 状态提升到contextProvider 并保留在那里,然后使用usePopupContext 挂钩检索它以及回调
    • 谢谢您能否修改您对此的回答,以便我也可以接受。
    猜你喜欢
    • 1970-01-01
    • 2021-03-07
    • 2021-10-08
    • 2019-09-08
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多