React Context使用报错:无法解构未定义的'emailLog'属性
问题分析
这个错误的核心原因很直接:Login组件不在EmailUser.Provider的包裹范围内,导致调用useContext(EmailUser)时返回undefined,解构emailLog自然就会报错。
解决方案
1. 扩大Provider的包裹范围到整个路由系统
你当前的App组件里,EmailUser.Provider只包了BasicExample和表单,但Login是路由跳转的页面,不在这个Provider的子组件树里。必须把Provider的范围扩大到整个路由容器,让所有需要访问Context的页面都被包裹。
修改后的App.js代码:
import React, { useState } from 'react'; import Axios from 'axios'; import { BrowserRouter as Router } from 'react-router-dom'; import BasicExample from './BasicExample'; // 给Context设置默认值,避免解构undefined报错 export const EmailUser = React.createContext({ emailLog: "", setEmailLog: () => {} }); function App() { Axios.defaults.withCredentials = true; const [invoice, setInvoice] = useState(""); const [currency, setCurrency] = useState("IDR"); const [myFile, setMyFile] = useState(""); const [emailLog, setEmailLog] = useState(""); return ( <EmailUser.Provider value={{ emailLog, setEmailLog }}> {/* 把整个路由系统放在Provider内部 */} <Router> <div className="App"> <BasicExample /> <div className="formInput"> <form method="POST" encType="multipart/form-data" action="http://localhost:3001/upload"> <div className="textUser"></div> <input className="inputForm" defaultValue={emailLog} type="email" disabled name="email" /> <input className="inputForm" type="number" placeholder="Invoice No" name="InvoiceNo" /> <input className="inputForm" type="date" name="Invoice_Date" /> <input className="inputForm" type="text" placeholder="Description" name="Description" /> <select className="selectBox" name="Currency" onChange={(e) => { setCurrency(e.target.value); }} > <option value="IDR">IDR</option> <option value="USD">USD</option> <option value="YEN">YEN</option> </select> <input className="inputForm" type="number" placeholder="Amount" name="Amount" /> <input className="custom-file-upload" multiple type="file" name="DocumentFile" onChange={(e) => { setMyFile(e.target.value); }} /> <button className="btnSubmit">Submit</button> </form> </div> </div> </Router> </EmailUser.Provider> ); } export default App;
2. 确认Login组件在路由配置中
检查你的BasicExample组件(路由配置组件),确保Login是路由的一部分,比如:
import { Routes, Route } from 'react-router-dom'; import Login from './Login'; import Home from './Home'; function BasicExample() { return ( <Routes> <Route path="/login" element={<Login />} /> <Route path="/home" element={<Home />} /> {/* 其他路由 */} </Routes> ); } export default BasicExample;
验证修改
重启项目后,访问Login页面:
- 输入邮箱时,
setEmailLog能正常更新Context状态 - 登录跳转至Home后,Home组件可以通过
useContext(EmailUser)拿到emailLog的值
内容的提问来源于stack exchange,提问作者RDK
相关产品推荐
相关产品推荐

