You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何在ShoppingList和Navbar组件间传递isLoggedIn登录状态

解决方案

首先纠正你现有代码的错误:你在ShoppingList组件内给useState添加export前缀的写法不符合React语法规范,Hook只能在组件顶层调用,无法直接导出组件内部的状态变量,这种方式不能实现跨组件状态共享。

根据组件层级不同,你可以选择以下两种常用方案实现需求:


方案1:状态提升(适用于两个组件是同级子组件、层级较近的场景)

将isLoggedIn状态提到两个组件的共同父组件(通常是App.jsx)中统一管理,再通过props透传给对应组件:

第一步:编写父组件逻辑(示例为App.jsx)

import React, { useState } from 'react'
import ShoppingList from './ShoppingList'
import Navbar from './Navbar'

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false)
  // 登出逻辑可根据自己的业务补充
  const handleLogout = () => {
    setIsLoggedIn(false)
    // 其他操作:清空本地存储、跳转登录页等
  }

  return (
    <div className="App">
      <Navbar isLoggedIn={isLoggedIn} handleLogout={handleLogout} />
      <ShoppingList setIsLoggedIn={setIsLoggedIn} />
    </div>
  )
}
export default App

第二步:修改ShoppingList组件

删除内部定义的isLoggedIn状态,接收父组件传入的setIsLoggedIn方法调用即可:

import React, { useState, useEffect } from 'react'
import axiosInstance from '../apis/apiURLS';

// 接收父组件传的setIsLoggedIn
function ShoppingList({ setIsLoggedIn }) {
  const [shoppingList, setShoppingList] = useState([])
  
  const getShoppingList = async () => {
    await axiosInstance.get('/shoppinglist/')
    .then(response => {
    if(response){
      // 调用父组件传的方法修改全局状态
      setIsLoggedIn(true)
      setShoppingList(response.data)
    }
  })
  .catch(e => {
    console.log(e);
  });
  }
  useEffect(() => {
    getShoppingList();
  }, [])
  // 其余原有逻辑保留
}
export default ShoppingList

第三步:修改Navbar组件

接收isLoggedIn参数做条件渲染控制按钮显隐:

function Navbar({ isLoggedIn, handleLogout }) {
  return (
    <div className='navbar'>
      {/* 登录状态为true时才渲染退出按钮 */}
      {isLoggedIn && (
        <div className='menu-bar-logout' onClick={handleLogout}>
          <div class="icon">
          </div>
          <span>Logout</span>
        </div>
      )}
    </div>
  )
}
export default Navbar

方案2:React Context(适用于组件层级深、多页面需要用到登录状态的场景)

不需要层层透传props,全局共享登录状态:

第一步:新建鉴权上下文文件src/context/AuthContext.jsx

import React, { createContext, useContext, useState } from 'react'

const AuthContext = createContext()

export function AuthProvider({ children }) {
  const [isLoggedIn, setIsLoggedIn] = useState(false)
  const handleLogout = () => {
    setIsLoggedIn(false)
    // 补充自己的登出业务逻辑
  }

  return (
    <AuthContext.Provider value={{ isLoggedIn, setIsLoggedIn, handleLogout }}>
      {children}
    </AuthContext.Provider>
  )
}
// 自定义Hook简化调用
export function useAuth() {
  return useContext(AuthContext)
}

第二步:全局包裹Provider(入口文件main.jsx)

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import { AuthProvider } from './context/AuthContext.jsx'

ReactDOM.createRoot(document.getElementById('root')).render(
  <AuthProvider>
    <App />
  </AuthProvider>,
)

第三步:ShoppingList中调用状态修改方法

import { useAuth } from '../context/AuthContext'

function ShoppingList() {
  const { setIsLoggedIn } = useAuth()
  const [shoppingList, setShoppingList] = useState([])
  
  const getShoppingList = async () => {
    await axiosInstance.get('/shoppinglist/')
    .then(response => {
      if(response){
        setIsLoggedIn(true)
        setShoppingList(response.data)
      }
    })
    // 其余逻辑不变
  }
  // 其余逻辑不变
}

第四步:Navbar中获取登录状态做渲染

import { useAuth } from '../context/AuthContext'

function Navbar() {
  const { isLoggedIn, handleLogout } = useAuth()
  return (
    <div className='navbar'>
      {isLoggedIn && (
        <div className='menu-bar-logout' onClick={handleLogout}>
          <div class="icon">
          </div>
          <span>Logout</span>
        </div>
      )}
    </div>
  )
}

内容的提问来源于stack exchange,提问作者silviaa11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:48:03