[英]Uncaught (in promise) Error: Invalid hook call on fetch()
我正在為 Django 開發一個網絡應用程序。這是一個簡單的博客。 前端是在 React 和 Materials UI 中構建的,它基於此處的教程,但我不得不自己進行很多調整,因為他使用的是面向類的方法,其中許多方法已被棄用,因為 React 似乎是朝着基於 model 的 function 邁進。在演示者創建的 model 中,我們通過使用生成 JSON 對象將數據從我們的反應前端傳遞到我們的 django 后端,882765404344488 序列化。 我建立了一個博客文章提交表單,但由於我無法理解的原因而無法正常工作。
創建BlogPost.js
import React, { Component } from "react";
import Grid from "@mui/material/Grid";
import { FormControl, FormHelperText, TextField, Typography, Button } from "@mui/material";
import { Link } from "react-router-dom";
import { useState } from "react";
import { Navigate } from "react-router-dom";
export default function CreateBlogPost(props) {
const[title,setTitle] = useState('');
const[content,setContent] = useState('');
const[tags, setTags] = useState('');
const handleTitle = event => {
setTitle(event.target.value);
}
const handleContent = event => {
setContent(event.target.value);
}
const handleTags = event => {
setTags(event.target.value);
}
const requestOptions = {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
title: title,
content: content,
tags: tags,
})
};
const handlePostButtonPressed = (requestOptions) => {
console.log(requestOptions)
fetch("/blog/create",requestOptions)
.then((response) => response.json())
.then((data) => Navigate('/posts/' + data.postid));
}
return (
<Grid container spacing={1} className="pl-2 pt-4">
<Grid item xs={12}>
<Typography component="h4" variant="h4">Create a post</Typography>
<Grid item xs={12} className="-ml-2 mt-4">
<FormHelperText>
<div>Title:</div>
</FormHelperText>
<FormControl>
<TextField required={true} type="text" value={title} onChange={handleTitle}/>
</FormControl>
</Grid>
</Grid>
<Grid item xs={12} className="-ml-2 mt-4">
<FormHelperText>
<div>Content:</div>
</FormHelperText>
<FormControl component="fieldset">
<TextField required={true} type="text" value={content} onChange={handleContent}/>
</FormControl>
</Grid>
<Grid item xs={12} className="-ml-2 mt-4">
<FormHelperText>
<div>Tags:</div>
</FormHelperText>
<FormControl component="fieldset">
<TextField required={true} type="text" value={tags} onChange={handleTags}/>
</FormControl>
</Grid>
<Grid item xs={12}>
<Button color="primary" variant="contained" onClick={handlePostButtonPressed}>
Post
</Button>
<Button color="secondary" variant="contained" to="/blogs/" component={Link}>
Back
</Button>
</Grid>
</Grid>
)
}
在我按下發布按鈕之前,這里的一切都正常工作。 在日志中,我看到我想提交的帖子的 JSON object 正確呈現(所以我知道這不是任何數據處理函數的錯誤),但我在獲取 function 時收到錯誤:
“未捕獲(承諾)錯誤:掛鈎調用無效。只能在 function 組件的主體內部調用掛鈎。這可能由於以下原因之一而發生:
我不相信我有不匹配的 React 版本。 這是我的 package.json:
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack watch --mode development ",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.20.7",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.0",
"glob-all": "^3.3.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.2.4",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
},
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.3",
"autoprefixer": "^10.4.13",
"css-loader": "^6.7.3",
"draft-js": "^0.11.7",
"postcss-cli": "^10.1.0",
"postcss-loader": "^7.0.2",
"react-draft-wysiwyg": "^1.15.0",
"react-router-dom": "^6.6.1",
"style-loader": "^3.3.1"
}
}
我研究了這個問題,但未能找到解決方案。 我發現了其他構建 forms 的方法,但這會改變我的后端接收數據的方式。 除非絕對必要,否則我寧願避免這種情況。
該代碼導入Navigate
組件並嘗試直接調用它。
import { Navigate } from "react-router-dom";
export default function CreateBlogPost(props) {
...
const handlePostButtonPressed = (requestOptions) => {
console.log(requestOptions)
fetch("/blog/create", requestOptions)
.then((response) => response.json())
.then((data) => Navigate('/posts/' + data.postid)); // <-- invoked here
};
...
在 React 中,我們不直接調用/調用 React 組件,我們在 React 組件的渲染返回中將它們渲染為 JSX ,即<Navigate to="..." />
。 通過將 React 組件直接調用為 function ,您將打破掛鈎規則(間接)。
Navigate
是一個組件,在呈現時會影響聲明性導航操作,即導航到指定的路由路徑。 我確定您打算導入useNavigate
掛鈎以使用navigate
function 並在處理程序中執行命令式導航操作。
導入useNavigate
並發出命令式導航操作。 刪除requestOptions
arg 並使用在requestOptions
組件 scope 中聲明的 requestOptions。這是因為handlePostButtonPressed
直接作為事件處理程序傳遞。
import { useNavigate } from "react-router-dom";
export default function CreateBlogPost(props) {
const navigate = useNavigate();
...
const requestOptions = {
method: "POST",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: title,
content: content,
tags: tags,
})
};
const handlePostButtonPressed = () => {
console.log(requestOptions)
fetch("/blog/create", requestOptions)
.then((response) => response.json())
.then((data) => navigate(`/posts/${data.postid}`);
};
...
<Button
color="primary"
variant="contained"
onClick={handlePostButtonPressed}
>
Post
</Button>
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.