react教程如何用路由基础语法使用跳转

 如果需要页面初始化参考这个回答链接:react初始化

本文是react教程如何用路由基础语法使用跳转,使用 JSX 语法定义一组路由规则,导入react-router-dom模块,通过Route定义路由路径,对应组件(注:/路径配(自定义的)组件)通过Link声明跳转

import { FC } from "react";
import {
  HashRouter as Router, // 声明路由模式
  Route, // 声明单个路由 path\element
  Routes, // 声明一组路由
  Link, //
  NavLink, // 声明式导航
  Navigate, // 路由重定向 代替v5 Redirect
} from "react-router-dom";

interface Props {}
const Index: FC<Props> = () => {
  return (
    <fieldset>
      <ul>
        <li>吃饭</li>
        <li>睡觉</li>
        <li>写代码</li>
        <li>打游戏</li>
        <li>旅行</li>
        <hr />
        组件匹配的内容
      </ul>
    </fieldset>
  );
};

export default Index;
// 定义一个名为eat的函数,用于表示吃饭的动作
const eat = () => {
  // 返回一个包含“吃饭”文字的h1元素,用于在网页上显示
  return <h1>吃饭</h1>;
};
const sleep = () => {
  return <h1>睡觉</h1>;
};
const code = () => {
  return <h1>写代码</h1>;
};
const game = () => {
  return <h1>打游戏</h1>;
};
const travel = () => {
  return <h1>旅行</h1>;
};

 {/* { 组件匹配的内容} */}
      {/* 使用 JSX 语法定义一组路由规则 */}
      <Routes>
        {/* 当 URL 路径为 "/eat" 时,渲染 Eat 组件 */}
        <Route path="/eat" element={<Eat />} />
        {/* // 当 URL 路径为 "/sleep" 时,渲染 Sleep 组件 */}
        <Route path="/sleep" element={<Sleep />} />
        {/* // 当 URL 路径为 "/code" 时,渲染 Code 组件 */}
        <Route path="/code" element={<Code />} />
        {/* // 当 URL 路径为 "/game" 时,渲染 Game 组件 */}
        <Route path="/game" element={<Game />} />
        {/* // 当 URL 路径为 "/travel" 时,渲染 Travel 组件 */}
        <Route path="/travel" element={<Travel />} />
      </Routes>

 报错:Cannot destructure property 'basename' of 'react__WEBPACK_IMPORTED_MODULE_0__.useContext(...)' as it is null.
TypeError: Cannot destructure property 'basename' of 'react__WEBPACK_IMPORTED_MODULE_0__.useContext(...)' as it is null.
    at LinkWithRef (http://localhost:3000/static/js/bundle.js:38142:5)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:24283:22)
    at updateForwardRef (http://localhost:3000/static/js/bundle.js:27532:24)
    at beginWork (http://localhost:3000/static/js/bundle.js:29593:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:14539:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:14583:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:14640:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:34538:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:33786:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:33709:9)
ERROR
Cannot destructure property 'basename' of 'react__WEBPACK_IMPORTED_MODULE_0__.useContext(...)' as it is null.
TypeError: Cannot destructure property 'basename' of 'react__WEBPACK_IMPORTED_MODULE_0__.useContext(...)' as it is null.
    at LinkWithRef (http://localhost:3000/static/js/bundle.js:38142:5)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:24283:22)
    at updateForwardRef (http://localhost:3000/static/js/bundle.js:27532:24)
    at beginWork (http://localhost:3000/static/js/bundle.js:29593:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:14539:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:14583:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:14640:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:34538:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:33786:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:33709:9)

原因:Link 组件需要被包裹在 <Router> 组件中

App.tsx中的代码: 

// App.tsx代码
import { FC } from "react";
import {
  HashRouter as Router, // 声明路由模式
  Route, // 声明单个路由 path\element
  Routes, // 声明一组路由
  Link, //
  NavLink, // 声明式导航
  Navigate, // 路由重定向 代替v5 Redirect
} from "react-router-dom";

// 定义一个名为eat的函数,用于表示吃饭的动作
const Eat = () => (
  // 返回一个包含“吃饭”文字的h1元素,用于在网页上显示
  <h1>吃饭</h1>
);

const Sleep = () => <h1>睡觉</h1>;

const Code = () => <h1>写代码</h1>;

const Game = () => <h1>打游戏</h1>;

const Travel = () => <h1>旅行</h1>;

interface Props {}
const Index: FC<Props> = () => {
  return (
    <Router>
      <ul>
        <li>
          <Link to="/eat">吃饭</Link>
        </li>
        <li>
          <Link to="/sleep">睡觉</Link>
        </li>
        <li>
          <Link to="/code">敲代码</Link>
        </li>
        <li>
          <Link to="/game">打游戏</Link>
        </li>
        <li>
          <Link to="/travel">旅行</Link>
        </li>
      </ul>
      <hr /> 
      {/* { 组件匹配的内容} */}
      {/* 使用 JSX 语法定义一组路由规则 */}
      <Routes>
        {/* 当 URL 路径为 "/eat" 时,渲染 Eat 组件 */}
        <Route path="/" element={<Eat />} />
        {/* // 当 URL 路径为 "/sleep" 时,渲染 Sleep 组件 */}
        <Route path="/sleep" element={<Sleep />} />
        {/* // 当 URL 路径为 "/code" 时,渲染 Code 组件 */}
        <Route path="/code" element={<Code />} />
        {/* // 当 URL 路径为 "/game" 时,渲染 Game 组件 */}
        <Route path="/game" element={<Game />} />
        {/* // 当 URL 路径为 "/travel" 时,渲染 Travel 组件 */}
        <Route path="/travel" element={<Travel />} />
      </Routes>
    </Router>
  );
};

export default Index;

index.tsx中的代码:

// 导入 createRoot
import { createRoot } from 'react-dom/client';

// 导入 App根组件
import App from './App'; 

import React from 'react';

// 创建 root
const root = createRoot(document.querySelector('#root') as HTMLElement) ;

// 调用 root 的render方法渲染
root.render(<App />);

效果:点击不同路由,跳转不同的 组件

<think>好的,用户遇到了React使用useContext时返回null导致无法解构basename的问题,错误提示是TypeError: Cannot destructure property 'basename' of 'react useContext' as it is null。我需要帮他解决这个问题。 首先,我得回忆一下React的Context机制。当使用useContext时,如果组件不在对应的Provider的包裹下,Context的值会是默认值,通常是undefined或者null。所以用户的问题很可能是因为没有在组件树的上层提供对应的Context.Provider,或者Provider的value没有被正确设置。 接下来,我需要检查代码结构。用户应该有一个通过React.createContext创建的Context对象,比如const MyContext = React.createContext(null);,然后在顶层组件中使用<MyContext.Provider value={{ basename: 'example' }}>来包裹子组件。如果用户没有正确包裹,或者Provider的value没有传递正确的值,就会导致解构失败。 然后,考虑可能的情况:用户可能在某个组件中直接使用useContext来获取Context的值,但该组件没有被对应的Provider包裹。比如,可能在路由配置中没有正确包裹Provider,或者在组件树中遗漏了Provider的添加。这时候,useContext返回的就是Context的默认值,也就是null,解构basename就会出错。 解决方法应该是确保所有使用该Context的组件都被对应的Provider包裹,并且Provider的value属性正确设置了包含basename的对象。另外,用户可能在创建Context时没有设置默认值,或者设置成了null,这时候如果未提供Provider,就会导致问题。建议在创建Context时提供一个合理的默认值,或者在解构时使用默认值来避免错误。 另外,用户可能在使用过程中,动态加载组件或者异步渲染导致Provider未及时渲染,这时候也需要检查组件加载的顺序和时机。如果使用React.lazy或者Suspense,需要确保Provider在异步组件加载之前就已经存在。 还需要检查是否有拼写错误,比如Context的引入是否正确,变量名是否一致。比如,可能在Provider中使用的是不同的Context对象,或者在useContext时引用了错误的Context变量。 总结步骤应该是:1. 确认Context的创建和Provider的设置是否正确;2. 检查组件是否被Provider包裹;3. 确保value属性正确传递了包含basename的对象;4. 在解构时提供默认值或进行空值检查;5. 检查拼写和引入是否正确。 最后,可能需要用户提供相关代码片段,以便更具体地诊断问题,但根据现有信息,以上步骤是常见的解决方法。</think>### 解决React中`useContext`返回`null`导致无法解构`basename`的问题 #### 问题原因分析 该错误`TypeError: Cannot destructure property 'basename' of 'react useContext' as it is null`通常发生在以下场景: 1. **未正确包裹Context Provider**:使用`useContext`的组件未被对应的`<YourContext.Provider>`包裹,导致上下文值为`null`[^5]。 2. **未设置默认值**:创建`Context`时未提供默认值,且未通过`Provider`传递值。 3. **异步加载问题**:动态加载组件时,`Provider`未及时渲染或未正确挂载。 --- #### 解决步骤 ##### 1. 检查Context定义与Provider包裹 确保`Context`的创建和`Provider`的包裹逻辑正确: ```javascript // 创建Context时建议设置合理的默认值 const BasenameContext = React.createContext({ basename: "/default" }); // 在顶层组件(如App组件)中包裹Provider function App() { return ( <BasenameContext.Provider value={{ basename: "/my-app" }}> <YourComponent /> </BasenameContext.Provider> ); } ``` ##### 2. 添加空值保护 在使用`useContext`解构时,增加空值判断或默认值: ```javascript function YourComponent() { const context = useContext(BasenameContext); // 方式1:条件判断 if (!context) return null; const { basename } = context; // 方式2:解构时提供默认值 const { basename = "/fallback" } = useContext(BasenameContext) || {}; } ``` ##### 3. 验证动态加载逻辑 若使用动态加载(如`React.lazy`),确保`Provider`在加载路径中: ```javascript const LazyComponent = React.lazy(() => import("./LazyComponent")); function App() { return ( <Suspense fallback={<div>Loading...</div>}> <BasenameContext.Provider value={{ basename: "/dynamic" }}> <LazyComponent /> </BasenameContext.Provider> </Suspense> ); } ``` ##### 4. 使用TypeScript类型检查(可选) 通过类型定义强制约束上下文结构,避免解构错误: ```typescript interface BasenameContextType { basename: string; } const BasenameContext = React.createContext<BasenameContextType | null>(null); // 使用时明确类型 const context = useContext(BasenameContext); if (!context) throw new Error("Missing Provider"); const { basename } = context; ``` --- #### 典型错误场景 - **路由配置遗漏**:在React Router等库中,若未在路由根组件包裹`Provider`,子路由组件可能无法获取上下文。 - **条件渲染未覆盖**:当`Provider`的渲染依赖某些状态(如API返回结果),未处理加载中状态可能导致`context`为`null`。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值