React页面间变量传递异常:无法获取selectedCompany值
问题原因
你的代码存在两个核心问题,导致无法获取正确的selectedCompany值:
- 直接调用组件函数无法获取目标实例状态:
StartSide()会创建一个全新的StartSide组件实例,这个实例的状态和用户点击操作的那个页面实例完全独立,所以拿到的永远是状态初始值''。 - 组件状态是内部私有属性:React通过
useState声明的状态属于组件实例私有,不能通过组件函数直接访问其他实例的状态。
解决方案
以下是几种适配你场景的解决方法,按推荐优先级排序:
方案1:路由传参(最适合当前跳转场景)
利用react-router-dom的navigate方法传递参数,在目标页面接收:
修改StartSide.js的点击事件:
const handleClickNOA = () => { const company = 'NOA'; setSelectedCompany(company); // 传递状态到目标路由 navigate('/tilbudside', { state: { selectedCompany: company } }); };
修改TilbudSide.js接收参数:
import React, { useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; // 引入useLocation function TilbudSide () { const [selectedCustomer, setSelectedCustomer] = useState(null); const [selectedCustomerNumber, setSelectedCustomerNumber] = useState(null); const location = useLocation(); // 获取路由携带的状态 let apiUrlCostumers = null; // 读取传递的参数,可选链避免无参数时报错 const selectedCompany = location.state?.selectedCompany; console.log('SELECTEDCOMPANY '+ selectedCompany ); if (selectedCompany === 'NOA') { apiUrlCostumers = 'http://localhost:8000/customers'; }; console.log(apiUrlCostumers) return ( <div className="tilbud-side"> <h2>Lag tilbud</h2> </div> ); } export default TilbudSide;
方案2:React Context(适合多组件共享状态场景)
如果后续有多个组件需要共享selectedCompany状态,可以用Context统一管理:
1. 创建Context文件(如CompanyContext.js):
import { createContext, useContext, useState } from 'react'; const CompanyContext = createContext(); export function CompanyProvider({ children }) { const [selectedCompany, setSelectedCompany] = useState(''); return ( <CompanyContext.Provider value={{ selectedCompany, setSelectedCompany }}> {children} </CompanyContext.Provider> ); } export function useCompany() { return useContext(CompanyContext); }
2. 在根组件包裹Provider(如App.js):
import { CompanyProvider } from './CompanyContext'; import { Routes, Route } from 'react-router-dom'; import StartSide from './StartSide'; import TilbudSide from './TilbudSide'; function App() { return ( <CompanyProvider> <Routes> <Route path="/" element={<StartSide />} /> <Route path="/tilbudside" element={<TilbudSide />} /> </Routes> </CompanyProvider> ); } export default App;
3. 修改StartSide.js使用Context:
import { useNavigate } from "react-router-dom"; import { useCompany } from './CompanyContext'; import logo from './assets/NA_logo.svg'; import './StartSide.css'; function StartSide() { const { setSelectedCompany } = useCompany(); const navigate = useNavigate() const handleClickNOA = () => { setSelectedCompany('NOA'); navigate('/tilbudside'); }; return ( <div onClick={handleClickNOA} style={{ cursor: 'pointer' }}> <img src={logo} className="NA-logo" alt="NA Logo" /> </div> ); } export default StartSide;
4. 修改TilbudSide.js使用Context:
import React, { useState, useEffect } from 'react'; import { useCompany } from './CompanyContext'; function TilbudSide () { const [selectedCustomer, setSelectedCustomer] = useState(null); const [selectedCustomerNumber, setSelectedCustomerNumber] = useState(null); const { selectedCompany } = useCompany(); let apiUrlCostumers = null; console.log('SELECTEDCOMPANY '+ selectedCompany ); if (selectedCompany === 'NOA') { apiUrlCostumers = 'http://localhost:8000/customers'; }; console.log(apiUrlCostumers) return ( <div className="tilbud-side"> <h2>Lag tilbud</h2> </div> ); } export default TilbudSide;
方案3:本地存储(适合持久化状态场景)
如果需要页面刷新后状态不丢失,可以使用localStorage:
修改StartSide.js:
const handleClickNOA = () => { const company = 'NOA'; setSelectedCompany(company); localStorage.setItem('selectedCompany', company); // 存入本地存储 navigate('/tilbudside'); };
修改TilbudSide.js:
function TilbudSide () { const [selectedCustomer, setSelectedCustomer] = useState(null); const [selectedCustomerNumber, setSelectedCustomerNumber] = useState(null); const selectedCompany = localStorage.getItem('selectedCompany'); // 读取本地存储 let apiUrlCostumers = null; console.log('SELECTEDCOMPANY '+ selectedCompany ); if (selectedCompany === 'NOA') { apiUrlCostumers = 'http://localhost:8000/customers'; }; console.log(apiUrlCostumers) return ( <div className="tilbud-side"> <h2>Lag tilbud</h2> </div> ); }
内容的提问来源于stack exchange,提问作者abh
相关产品推荐
相关产品推荐

