我不知道如何找出我的问题——反应



我是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)

尝试将open状态放入应用程序组件中,并将其从模态组件中删除:

const [errors, setErrors] = useState([]);
const [isModalOpen, setIsModalOpen] = useState(false);
useEffect(() => {
if(errors.length > 0) setIsModalOpen(true);
}, [errors])
<Modal
...
isOpen={isModalOpen}
setIsOpen={setIsModalOpen}
/> 

最新更新