如何使用react和typescript在基于url的useeffect中更新状态?

时间:2020-07-21 02:50:34

标签: reactjs typescript

当用户位于页面“ / items /:itemId”中时,我想使用react和typescript将right属性从16px更改为40px。

下面是我的代码段

const root = () => {
    <PopupContextProvider>
        <App/>
    </PopupContextProvider>
}


export const PopupContextProvider = ({ children }: any) => {
    return (
        <popupContext.Provider value={context}>
            {children}
            {(condition1 || condition2) && (
                <Popup onHide={dismiss} />
            )}
        </popupContext.Provider>
    );
}

export function Popup({ onHide }: Props) {
    const location = useLocation();
    const [isView, setIsView] = React.useState(false);
    if (location.pathname === '/items/:itemId') {
        setIsView(true);//here doesnt change to true. how can i do the same 
        //in useeffect or something that updates 
    }
    return (
        <Dialog isView={isView}>
            <DialogBody>
                <span>Title</span>
                <Description/>
            </DialogBody>
            <Actions>
                <span>Hide</span>
            </Actions>
        </Dialog>
    );
}


const Dialog = styled.div<isView?:boolean>`
    position: fixed;
    ${({ isView }) => isView && 'right:  40px;'}
    display: flex;
    flex-direction: column;
`;

在以上代码段中,我检查了位置并将isView状态更新为true。

现在,即使用户位于页面“ / items /:itemId”中,isView也不会从false更新为true。

如何更新useeffect中的状态?

有人可以帮我吗?谢谢。

1 个答案:

答案 0 :(得分:0)

您根本不需要isView状态,只需将其设置为const

export function Popup({ onHide }: Props) {
    const location = useLocation();
    const isView = location.pathname === '/items/:itemId';
    return (
        <Dialog isView={isView}>
            <DialogBody>
                <span>Title</span>
                <Description/>
            </DialogBody>
            <Actions>
                <span>Hide</span>
            </Actions>
        </Dialog>
    );
}

仅当您需要记住确实发生变化的事情(例如用户在React释放组件时输入信息或单击按钮)时需要状态。但是,在这种情况下,您可能无需重新加载页面并获取组件的新实例就不会更改路径。

如果您真的想使用useEffect,则可以将一个空数组用作第二个arg,这意味着它仅在像React类中的componentDidMount创建组件时才运行。

export function Popup({ onHide }: Props) {
    const location = useLocation();
    const [isView, setIsView] = React.useState(false);
    useEffect(() => {
        if (location.pathname === '/items/:itemId') {
            setIsView(true);//here doesnt change to true. how can i do the same 
            //in useeffect or something that updates 
        }
    }, []);
    return (
        <Dialog isView={isView}>
            <DialogBody>
                <span>Title</span>
                <Description/>
            </DialogBody>
            <Actions>
                <span>Hide</span>
            </Actions>
        </Dialog>
    );
}

您可能会收到警告,需要在末尾将isView添加到空数组中。 React希望您观察正在修改的值,并在它们更改时调用useEffect。您可以添加它,但是它很奇怪,因为它永远不会改变。

您可以将isView存储在ref中,然后您将不会收到警告,因为ref更新不会导致重新渲染,但是再次没有理由存储此变量以进行重新渲染轻松快捷地进行计算。