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

React.js中函数嵌套及全局调用Token操作服务的实现方法

Hey there! Let's tackle your questions about React step by step—covering global token utilities, "service-like" patterns, and function nesting best practices.

1. Implementing Global Token Operations in React

React doesn't have a built-in "package/service" system out of the box, but there are several straightforward ways to make your token functions accessible across all components. Here are the most common approaches:

Option 1: Utility Module (Simplest for Static Logic)

Create a standalone utility file to encapsulate your token logic—this is perfect if you don't need to tie token state to React's component lifecycle.

// src/utils/tokenService.js
export const tokenService = {
  setToken(token, expiration) {
    localStorage.setItem('token', token);
    localStorage.setItem('expiration', expiration);
  },
  getToken() {
    const token = localStorage.getItem('token');
    const expiration = localStorage.getItem('expiration');
    
    if (!token || !expiration) return null;
    
    if (Date.now() > parseInt(expiration)) {
      this.destroyToken();
      return null;
    }
    
    return token;
  },
  destroyToken() {
    localStorage.removeItem('token');
    localStorage.removeItem('expiration');
  }
};

Then import and use it in any component:

import { tokenService } from '../utils/tokenService';

function LoginButton() {
  const handleLogin = () => {
    // Set a token that expires in 1 hour
    tokenService.setToken('user-123-token', Date.now() + 3600000);
  };

  return <button onClick={handleLogin}>Log In</button>;
}

function UserProfile() {
  const token = tokenService.getToken();
  
  return (
    <div>
      {token ? `Welcome back! Token: ${token.slice(0, 10)}...` : 'Please log in'}
    </div>
  );
}

Option 2: React Context + Custom Hook (For State-Linked Logic)

If you want token changes to trigger component re-renders (e.g., updating UI when a token expires), use React Context to wrap your app with token state and operations.

// src/contexts/TokenContext.js
import { createContext, useContext, useCallback, useEffect, useState } from 'react';

const TokenContext = createContext();

export function TokenProvider({ children }) {
  const [currentToken, setCurrentToken] = useState(null);

  const setToken = useCallback((token, expiration) => {
    localStorage.setItem('token', token);
    localStorage.setItem('expiration', expiration);
    setCurrentToken(token);
  }, []);

  const getToken = useCallback(() => {
    const storedToken = localStorage.getItem('token');
    const expiration = localStorage.getItem('expiration');
    
    if (!storedToken || !expiration) return null;
    
    if (Date.now() > parseInt(expiration)) {
      destroyToken();
      return null;
    }
    
    return storedToken;
  }, []);

  const destroyToken = useCallback(() => {
    localStorage.removeItem('token');
    localStorage.removeItem('expiration');
    setCurrentToken(null);
  }, []);

  // Initialize token on app load
  useEffect(() => {
    setCurrentToken(getToken());
  }, [getToken]);

  return (
    <TokenContext.Provider value={{ currentToken, setToken, getToken, destroyToken }}>
      {children}
    </TokenContext.Provider>
  );
}

// Custom hook to access token context easily
export function useToken() {
  const context = useContext(TokenContext);
  if (!context) {
    throw new Error('useToken must be used within a TokenProvider');
  }
  return context;
}

Wrap your root app with the provider:

// src/App.js
import { TokenProvider } from './contexts/TokenContext';
import LoginButton from './components/LoginButton';
import UserProfile from './components/UserProfile';

function App() {
  return (
    <TokenProvider>
      <LoginButton />
      <UserProfile />
    </TokenProvider>
  );
}

Then use the custom hook in components:

// src/components/UserProfile.js
import { useToken } from '../contexts/TokenContext';

function UserProfile() {
  const { currentToken, destroyToken } = useToken();
  
  return (
    <div>
      {currentToken ? (
        <>
          <p>Logged in with token: {currentToken.slice(0, 10)}...</p>
          <button onClick={destroyToken}>Log Out</button>
        </>
      ) : (
        <p>Please log in</p>
      )}
    </div>
  );
}
2. Function Nesting in React

Function nesting is super common in React, but there are a few key things to keep in mind to avoid pitfalls:

Common Use Cases & Pitfalls

  • Event Handlers & Props: It's normal to nest event handlers inside components (like handleLogin above), but if you pass these nested functions as props to child components, every re-render of the parent will create a new function instance. This can trigger unnecessary re-renders in children.

    Fix it with useCallback to cache the function:

    import { useCallback } from 'react';
    
    function ParentComponent() {
      // Cached function—only recreated if dependencies change
      const handleClick = useCallback(() => {
        console.log('Button clicked!');
      }, []); // Empty dependency array = never recreated
    
      return <ChildComponent onClick={handleClick} />;
    }
    
  • Closure & Stale Values: Nested functions have access to variables from their outer scope (closure), but this can lead to "stale" values if you're not careful. For example, if you use a state variable inside an useEffect nested function, you need to include it in the dependency array:

    import { useState, useEffect } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const timer = setInterval(() => {
          // Without count in dependencies, this will always log 0!
          console.log(`Current count: ${count}`);
        }, 1000);
    
        return () => clearInterval(timer);
      }, [count]); // Add count to dependencies to get fresh values
    
      return <button onClick={() => setCount(count + 1)}>Increment</button>;
    }
    
  • Performance Overhead: Frequent creation of complex nested functions can add minor performance overhead, but in most cases, it's negligible. Prioritize readability first—only optimize with useCallback or useMemo if you notice actual performance issues.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:41:09