React类组件中调用fetch发起POST请求出现报错该如何解决?
React类组件Fetch请求报错解决方案
核心问题原因
你的代码核心错误是在类组件中违规使用了React Hook(useState、useHistory),React Hook仅支持在函数组件、自定义Hook的顶层调用,不能在类组件、普通函数、条件判断/循环中使用。
所有错误点梳理
- 错误1:在类组件的
handleChange方法内调用useState,既违反Hook使用规则,也导致定义的title、body、PostData变量仅在handleChange作用域内有效,render方法中完全访问不到,点击按钮会直接报变量未定义错误。 - 错误2:
useHistory是React Router v5提供的Hook,类组件中无法直接使用,你未定义history变量,调用history.push时也会报错。 - 错误3:
react-select的onChange回调返回的是选中的option对象,不是原生事件对象,你写的e.target.value无法拿到正确值。
修复后完整代码
import React, { Component, Fragment } from "react"; import Select from "react-select"; import { withRouter } from "react-router-dom"; const options = [ { value: "red", label: "red" }, { value: "blue", label: "blue" }, { value: "green", label: "green" } ]; class CrearPost extends Component { state = { selectedOption: null, title: "", body: "" }; // 处理select选择变化 handleSelectChange = selectedOption => { this.setState({ selectedOption, // 如果需要把选中的颜色值作为title,就打开下面一行 // title: selectedOption?.value || "" }) }; // 处理body输入变化 handleBodyChange = e => { this.setState({ body: e.target.value }) }; // 提交帖子方法 PostData = () => { fetch('/createpost', { method:'post', headers:{ 'Content-Type':'application/json', Authorization: "Bearer " + localStorage.getItem("jwt") }, body:JSON.stringify({ title: this.state.title, body: this.state.body }) }).then(res=>res.json()) .then(data=>{ console.log(data) if(data.error){ alert(data.error) } else{ alert('Post created') // 从props获取history对象跳转 this.props.history.push('/') } }).catch(err=>{ console.log(err) }) } render() { return ( <div align="center"> <Fragment> <Select className="basic-single" classNamePrefix="select" defaultValue={options[0]} isDisabled={false} isLoading={false} isClearable={true} isRtl={false} isSearchable={true} name="color" options={options} value={this.state.selectedOption} onChange={this.handleSelectChange} /> </Fragment> <input type="text" placeholder="body" value={this.state.body} onChange={this.handleBodyChange} /> <button onClick={this.PostData}> 提交帖子 </button> </div> ); } } // 用withRouter包裹组件,获取路由相关props export default withRouter(CrearPost);
修改说明
- 移除了所有Hook调用,所有状态统一放到类组件的
this.state中管理,使用this.setState修改状态 - 引入
withRouter高阶组件包裹组件,从组件props中获取history对象实现路由跳转 - 修正了
react-select的绑定逻辑,适配它的回调返回值格式 - 把所有方法提到类的顶层,避免作用域访问问题
内容的提问来源于stack exchange,提问作者asker
相关产品推荐
相关产品推荐

