reactjs - 我不知道如何解决我的问题 - 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)
解决方案
尝试将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}
/>
推荐阅读
- android-studio - Android Studio 安装在 SSD 上,但 Android Studio 使用 100% HDD
- qiskit - 如何让 Qiskit 教科书小部件工作?
- javascript - 使用角度在对象中更新/添加对象
- pandas - 使用 pandas 和 matplotlib 访问带有错误“urlopen 错误隧道连接失败”的 URL 的问题
- java - 无法读取字符串的输入
- postgresql - 服务器是否在本地运行并接受 Unix 域套接字“/var/run/postgresql/.s.PGSQL.5432”上的连接?
- c++ - 为什么用作嵌套成员的非模板类是不完整类型?
- spring - 我们可以在 Spring Boot 的单个模块中同时定义 Bearer 令牌认证和基本认证吗?
- r - R vs Excel:过滤后的结果不一致
- php - 如何使用 PHP foreach 数组循环迭代 HTML?