首页 > 解决方案 > 我不知道如何解决我的问题 - React

问题描述

我对 React 很陌生,我遇到了一个问题,我不知道如何排除故障。因此,当自定义挂钩中的 http 请求失败时,我会在上下文中设置一个数组

这是我的钩子:

const useHttp = (requestObj: any, setData: Function) => 
{
    const [isLoading, setIsLoading] = useState(false); 
    const ctx = useContext(GlobalContext);
        
    const sendRequest = useCallback(() =>
    {
        setIsLoading(true);
        
        fetch(requestObj.url, {
            method: requestObj.method ? requestObj.method: 'GET',
            headers: requestObj.headers ? requestObj.headers : {},
            body: requestObj.body ? JSON.stringify(requestObj.body) : null
        })
        .then(res => res.json())
        .then(data => {
            setIsLoading(false);
            setData(data);                
        })
        .catch(err => 
        {
            setIsLoading(false); 
            ctx.setErrors([
            (prevErrors: string[]) =>
            {
                //prevErrors.push(err.message)
                let newArray = prevErrors.map((error) => {return error});
                newArray.push(err.message);
                return newArray;
            }]
        );
            console.log('There was an error');
        });
    }, []);

    return {
        isLoading: isLoading,
        sendRequest: sendRequest
    }
} 

我使用 .map 因为数组的扩展运算符不起作用。我正在研究它,但它对此并不重要。

当出现错误时,我创建一个模式,然后在我的 jsx 中呈现它。我的问题是,由于某种原因,我的 Modal 渲染了两次。第二次它没有道具,这炸毁了我的程序。我不知道为什么它再次渲染,我不知道如何解决这个问题。堆栈与导致它的原因无关(我可以看到)。如果组件再次渲染,道具会不会与最初使用的不一样?我在调用模态的地方有断点,它们不会再次被击中。那么任何人都可以就我如何进行调试提供一些建议吗?

const App: FC = () => {

    const [errors, setErrors] = useState([]);

    let modal = null

    if(errors.length > 0)
    {
        modal = ( 
            <Modal 
                heading="Warning" 
                content={<div>{errors}</div>}
                buttonList={
                    [
                        {label: "OK", clickHandler: ()=> {}, closesModal: true},
                        {label: "Cancel", clickHandler: ()=> {alert("cancelled")}, closesModal: false}
                    ]
                } 
                isOpen={true}/>
        )
    }

    return (
        <GlobalContext.Provider value={{errors: errors, setErrors: setErrors}}>
            <ProviderV3 theme={defaultTheme}>
                <Toolbar></Toolbar>
                <Grid
                    margin='25px'
                    columns='50% 50%'
                    gap='10px'
                    maxWidth='100vw'>
                    <OwnerSearch />
                    <NewOwnerSearch />
                </Grid>
            </ProviderV3>
            {modal}
        </GlobalContext.Provider>
    );
};


import { FC, useState } from 'react';

import {
    ButtonGroup, Button, DialogContainer,
    Dialog, Content, Heading, Divider
} from '@adobe/react-spectrum';

type Props = {
    heading: string,
    content : any,
    buttonList: {label: string, clickHandler: Function, closesModal: boolean}[],
    isOpen: boolean
}

const Modal: FC<Props> = ( props ) =>
{
    const [open, setOpen] = useState(props.isOpen);

    let buttons = props.buttonList.map((button, index) =>
    {
        return <Button key={index} variant="cta" onPress={() => close(button.clickHandler, button.closesModal)} autoFocus>
            {button.label}
        </Button>
    });

    const close = (clickHandler: Function | null, closesModal: boolean) =>
    {
        if(clickHandler != null)
        {
            clickHandler()
        }
        if(closesModal)
        {
            setOpen(false)
        }
    }

    return ( 
        <DialogContainer onDismiss={() => close(null, true)} >
            {open &&
                <Dialog>
                    <Heading>{props.heading}</Heading>
                    <Divider />
                    <Content>{props.content}</Content>
                    <ButtonGroup>
                        {buttons}
                    </ButtonGroup>
                </Dialog>
            }
        </DialogContainer>
    );
}

export default Modal;

按照消防员的建议,我现在收到一个错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
    at resolveDispatcher (react.development.js:1476)
    at useContext (react.development.js:1484)
    at useProvider (module.js:239)
    at $bc3300334f45fd1ec62a173e70ad86$var$Provider (module.js:95)
    at describeNativeComponentFrame (react-dom.development.js:946)
    at describeFunctionComponentFrame (react-dom.development.js:1034)
    at describeFiber (react-dom.development.js:1119)
    at getStackByFiberInDevAndProd (react-dom.development.js:1138)
    at createCapturedValue (react-dom.development.js:20023)
    at throwException (react-dom.development.js:20351)

标签: reactjs

解决方案


尝试将open状态放入 App 组件中并将其从 Modal 组件中删除:

const [errors, setErrors] = useState([]);
const [isModalOpen, setIsModalOpen] = useState(false);

useEffect(() => {
    if(errors.length > 0) setIsModalOpen(true);
}, [errors])

<Modal
   ...
   isOpen={isModalOpen}
   setIsOpen={setIsModalOpen}
/> 

推荐阅读