求助:如何在React的分离文件组件之间传递Hook状态
Hey there, let's break down why your current code isn't working and walk through solid solutions to share the career state between your components.
The Core Issue
Your mistake here is trying to access MenuPopupState.career directly—function components in React keep their state private and encapsulated inside the component itself. MenuPopupState is just the component function, not an instance, so you can't pull internal state out of it like that. Also, your original setCareer(career) in the button click won't actually update the state (you're just setting it to its current value).
Solution 1: Lift State Up (React's Recommended Approach)
For simple component relationships, move the shared state to the nearest common parent component, then pass it down via props to both Header and MenuPopupState.
- Create a parent component (e.g.,
App.jsx) to hold the state:
// App.jsx import React, { useState } from 'react'; import MenuPopupState from './file1'; import Header from './file2'; function App() { // Move the career state here, so both child components can access it const [career, setCareer] = useState(null); return ( <div> <Header career={career} /> <MenuPopupState setCareer={setCareer} /> </div> ); } export default App;
- Update
file1.jsxto use the passed-downsetCareerfunction:
// file1.jsx import * as React from 'react'; export default function MenuPopupState({ setCareer }) { // Update the click handler to set an actual career object (not just the current state) const handleButtonClick = () => { setCareer({ id: 1, name: 'Frontend Developer' }); }; return ( <div> <button onClick={handleButtonClick}>Press me</button> </div> ); }
- Update
file2.jsxto receive thecareerprop safely:
// file2.jsx import * as React from 'react'; export default function Header({ career }) { // Handle the case where no career is selected yet to avoid errors if (!career) return <div>No career selected</div>; return ( <div> <a key={career.id}>{career.name}</a> </div> ); }
Solution 2: Use React Context (For Deep Component Trees)
If your components are far apart in the component hierarchy and prop-drilling becomes messy, React Context is a better fit.
- Create a Context file to hold the state logic:
// CareerContext.jsx import React, { createContext, useState, useContext } from 'react'; // Create the context const CareerContext = createContext(); // Create a provider component to wrap your app export function CareerProvider({ children }) { const [career, setCareer] = useState(null); return ( <CareerContext.Provider value={{ career, setCareer }}> {children} </CareerContext.Provider> ); } // Create a custom hook to easily access the context export function useCareer() { return useContext(CareerContext); }
- Wrap your app with the provider in
App.jsx:
// App.jsx import React from 'react'; import MenuPopupState from './file1'; import Header from './file2'; import { CareerProvider } from './CareerContext'; function App() { return ( <CareerProvider> <Header /> <MenuPopupState /> </CareerProvider> ); } export default App;
- Update
file1.jsxto use the context hook:
// file1.jsx import * as React from 'react'; import { useCareer } from './CareerContext'; export default function MenuPopupState() { const { setCareer } = useCareer(); const handleButtonClick = () => { setCareer({ id: 1, name: 'Frontend Developer' }); }; return ( <div> <button onClick={handleButtonClick}>Press me</button> </div> ); }
- Update
file2.jsxto use the context hook:
// file2.jsx import * as React from 'react'; import { useCareer } from './CareerContext'; export default function Header() { const { career } = useCareer(); if (!career) return <div>No career selected</div>; return ( <div> <a key={career.id}>{career.name}</a> </div> ); }
Both solutions will let you access and update the career state across your components properly. Start with state lifting if your component structure is simple—Reserve Context for when prop-drilling becomes unmanageable.
内容的提问来源于stack exchange,提问作者CxrlosKenobi

