我收到此错误:
Uncaught runtime errors:
ERROR
Rendered fewer hooks than expected. This may be caused by an accidental early return statement.
at renderWithHooks (http://localhost:3000/static/js/bundle.js:28072:15)
at updateFunctionComponent (http://localhost:3000/static/js/bundle.js:31574:24)
at beginWork (http://localhost:3000/static/js/bundle.js:33293:20)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:18263:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:18307:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:18364:35)
at beginWork$1 (http://localhost:3000/static/js/bundle.js:38262:11)
at performUnitOfWork (http://localhost:3000/static/js/bundle.js:37510:16)
at workLoopSync (http://localhost:3000/static/js/bundle.js:37433:9)
at renderRootSync (http://localhost:3000/static/js/bundle.js:37406:11
根据我所读到的内容,如果在条件语句中调用钩子,或者如果我将 return 语句放在钩子调用之上,等等,就会发生这种情况。
当我单击此按钮时会引发错误(这应该将我导航到另一个页面):
<Col xs={1} className="myCol"><Button variant="info" value={v.id} onClick={(e) => requestMemberEdit(e.target.value, 'edit')}>Edit</Button></Col>
点击按钮时调用的函数是这样的:
const requestMemberEdit = (id, type) => {
navigate("/newmember", { state:{type:type, id: id }} );
}
在另一个文件中,我尝试使用
location
来获取单击按钮时发送的状态属性。
这是第一个文件的完整代码,其中包含我上面刚刚显示的代码(这是引发错误的代码)
import { useState, useEffect } from "react";
import { Container, Row, Col, Button } from 'react-bootstrap';
import { useNavigate } from "react-router-dom";
const ShowMembers = () => {
const [allMembers, setAllMembers] = useState({});
const [arg, setArg] = useState('');
const navigate = useNavigate();
useEffect(() => {
const getAllMembers = () => {
fetch('/getAllMembers')
.then(data => data.json())
.then(res => {
setAllMembers(res)
//console.log(allMembers)
})
.catch(err => {
console.log(err)
})
};
getAllMembers();
}, []);
const requestMemberEdit = (id, type) => {
//console.log('xxxxxx ' + id)
navigate("/newmember", { state:{type:type, id: id }} );
}
const requestMemberDelete = (id) => {
if(window.confirm("Delete this member?")) {
fetch("/api/deleteMember", {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({id: parseInt(id)})
})
.then(res => res.json())
.then(res => {
res === true ? alert("User deleted")
: alert("Something went wrong, pls try again");
})
}
}
return (
<>
<div className="memberDiv">
<Container className="members">
{
allMembers.length ?
allMembers.map(v => <Row key={v.id}>
<Col className="myCol">{v.firstname}</Col>
<Col className="myCol">{v.lastname}</Col>
<Col className="myCol">{v.email}</Col>
<Col className="myCol">{v.birthdate}</Col>
<Col xs={1} className="myCol"><Button variant="danger" value={v.id} onClick={(e) => requestMemberDelete(e.target.value)}>Delete</Button></Col>
<Col xs={1} className="myCol"><Button variant="info" value={v.id} onClick={(e) => requestMemberEdit(e.target.value, 'edit')}>Edit</Button></Col>
</Row>)
: <h2>No data</h2>
}
</Container>
</div>
</>
)
}
export default ShowMembers;
如果您注意到此代码:
const [arg, setArg] = useState('');
。我不在任何地方使用它。我想删除它,并注意到删除后,它会给出另一条错误消息。此错误消息是:
Should have a queue. This is likely a bug in React. Please file an issue.
at updateReducer (http://localhost:3000/static/js/bundle.js:28232:15)
at updateState (http://localhost:3000/static/js/bundle.js:28600:14)
at Object.useState (http://localhost:3000/static/js/bundle.js:29397:20)
at useState (http://localhost:3000/static/js/bundle.js:47840:25)
at AddMember (http://localhost:3000/static/js/bundle.js:1161:84)
at renderPage (http://localhost:3000/static/js/bundle.js:289:70)
at Content (http://localhost:3000/static/js/bundle.js:302:10)
at renderWithHooks (http://localhost:3000/static/js/bundle.js:28005:22)
at updateFunctionComponent (http://localhost:3000/static/js/bundle.js:31572:24)
at beginWork (http://localhost:3000/static/js/bundle.js:33291:20)
尽管它说这可能是 React 中的一个错误,但我不认为它是。
这是另一个文件中的代码,我想在其中使用
location
import { useState } from "react";
import { Row, Col, Form, Button } from "react-bootstrap";
import { useLocation } from 'react-router-dom';
const AddMember = () => {
const [data, setData] = useState('');
const [oldMember, setOldMember] = useState('')
const location = useLocation();
console.log(location)
if(location.type === 'edit') {
fetch('/api/getMemberByID', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({id: location.id})
})
.then(data => data.json())
.then(res => {
setOldMember(res)
})
.catch(err => {
console.log('Could not set old member')
})
}
const handleChange = (e) => {
const { name, value } = e.target;
setData((prevData) => ({
...prevData,
[name]: value,
}));
};
const submitFormData = async (e) => {
e.preventDefault();
await fetch('/newmember', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => {
console.log("ffff:"+data);
})
.catch(err => {
console.log(err)
})
};
return (
<div className="contentDiv">
<Form onSubmit={submitFormData} name="formdata" id="formdata">
<Form.Group className="mb-3" controlId="formBasicEmail">
<Row>
<Col>
<Form.Label>First name</Form.Label>
<Form.Control type="text" placeholder="Fornavn" value={oldMember ? oldMember.firstname : ''} name="firstname" required onChange={handleChange} />
</Col>
<Col>
<Form.Label>Last name</Form.Label>
<Form.Control type="text" placeholder="Efternavn" value={oldMember ? oldMember.lastname : ''} name="lastname" required onChange={handleChange} />
</Col>
<Col>
<Form.Label>Email</Form.Label>
<Form.Control type="text" placeholder="Email" value={oldMember ? oldMember.email : ''} name="email" required onChange={handleChange} />
</Col>
</Row>
<Row>
<Col>
<Form.Label>Birthday</Form.Label>
<Form.Control type="date" placeholder="Fødselsdag" name="bday" required onChange={handleChange} />
</Col>
<Col>
<Form.Label>Sport</Form.Label>
<Form.Select aria-label="Default select example" name="sport" type="number" onChange={handleChange} >
<option>Vælg aktivitet</option>
<option value="1">Hobby 1</option>
<option value="2">Hobby 2</option>
<option value="3">Hobby 3</option>
</Form.Select>
</Col>
<Col>
<Form.Check type="checkbox" name="active" label="Active" onChange={handleChange} />
</Col>
</Row>
<Row>
<Col>
<Form.Label>Chip</Form.Label>
<Form.Control type="text" name="chip" placeholder="Add chip" onChange={handleChange}/>
</Col>
</Row>
</Form.Group>
<Button type="submit"> Submit</Button>
</Form>
</div>
)
}
export default AddMember;
如果它很重要,我正在使用
BrowserRouter
function App() {
return (
<>
<Buttons />
<BrowserRouter>
<Routes>
<Route path='/' element={<Content />}></Route>
<Route path='/newmember' element={<Content />}></Route>
<Route path='/ShowMembers' element={<Content />}></Route>
<Route path='/ShowAdmins' element={<Content />}></Route>
<Route path='/NewAdmin' element={<Content />}></Route>
<Route path='*' element={<PageNotFound />}></Route>
</Routes>
</BrowserRouter>
</>
);
}
export default App;
<Content />
函数中引用的我的
App()
组件看起来像这样:
const Content = () => {
const URL = window.location.pathname.split('/')[1];
const renderPage = (url) => {
switch (url) {
case 'newmember':
return AddMember()
case 'NewAdmin':
return AddAdmin()
case 'showMemberByMail':
return ShowMembers()
case 'ShowMembers':
return ShowMembers()
case 'ShowAdmins':
return ShowAdmins()
default:
return PageNotFound()
}
}
return (
renderPage(URL)
)
}
作为 React 新手,我并没有考虑在组件上使用 JSX 语法,所以相反,我最终像常规函数一样调用它们,这导致了奇怪的行为,尤其是上面描述的问题,这就是这篇文章的原因。 所以我解决这个问题的方法是使用 JSX 语法渲染组件。这是现在的样子,解决了我的头痛/问题
const Content = () => {
const URL = window.location.pathname.split('/')[1];
const renderPage = (url) => {
switch (url) {
case 'newmember':
return <AddMember />
case 'NewAdmin':
return <AddAdmin />
case 'showMemberByMail':
return <ShowMembers />
case 'ShowMembers':
return <ShowMembers />
case 'ShowAdmins':
return <ShowAdmins />
default:
return <PageNotFound />
}
}
return (
renderPage(URL)
)
}
如果我将此文件与上面的其他文件一起发布,人们可能会发现我的问题,但我不知道这个文件/代码会是问题