React脚手架开发纪实

151 阅读4分钟

创建官方React脚手架地址

目录展示

  • img

npm 和 npx区别

blog.csdn.net/qq_45947664…

版本渲染方式差异:

  • 17版本之前
  • 17版本以后

reactDOM 是react 网页开发的一个类库

使用<React.StrictMode />会导致useEffect()多次执行

在脚手架当中才能这样使用闭合标签<App />\

react-router路由官方文档

npm install react-router-dom

React-Router的使用

  • 首要问题就是:
  • 1 如何配置
  • 2 如何跳转
  • 3 如何传参或获取参数

路由配置方式:

第一种 使用 RouterProvider 目前官方推荐的方式

在router/index.js

//引入路由API
import {
    createBrowserRouter,
    RouterProvider,
    useNavigate
  } from "react-router-dom";
  import { useEffect } from "react";

在router/index.js

// 自己声明了一个 重定向组件
const Redirect = ()=>{
    const navigate = useNavigate()
    //组件挂载时进行挂载
    useEffect(()=>{
        navigate('/index')
    },[])
   
    return <List />
}
//创建路由
const router = createBrowserRouter([
    {
      path: "/",
      element: <Layout/>,
      //子路由
      children:[
        {
            path:'index',
            element:<List />
        },
        {
            path:'list',
            element:<About/>
        },
        {
            path:'/',
            element:<Redirect />
        },
      ]new
    },ew
    {
      path: "/new",
      element: <New/>,
    },
    {
      path: "/about",
      element: <About/>,
    },
      //使用params 动态参数
      {
        path: "/detail/:id",
        element: <Detail />,
      },
      //404路由
      {
        path:'*',
        element:<div>404</div>
      }
  ]);

在index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
//使用RouterProvider来加载路由对象
root.render( <RouterProvider router={router} />)

第二种方式 使用 BrowserRouter 或者 HashRouter组件 (目前应用最广泛的)

在index.js

//引入路由API
import {
  BrowserRouter  as Router, //用于浏览器路由模式 历史记录模式
  HashRouter, //用于切换路由模式 哈希模式
  Routes,
  Route,
  Navigate,
} from "react-router-dom";

在index.js

  //  使用路由来渲染根组件  BrowserRouter 或 HashRouter 来配置路由  配置方式2
  <Router>
    <Routes>
      <Route path='/' element={<Layout />}>
        <Route path='home' element={<Home />}></Route>
        <Route path='new' element={<New />}></Route>
        <Route path='/' element={<Navigate to='home'></Navigate>}></Route> //重定向路由配置
    </Route>
    <Route path='/about' element={<About />}></Route>
    <Route path='*' element={<div >404</div>}></Route>
  </Routes>
  </Router >

第三种方式 使用路由来渲染根组件 useRoute 来配置路由  配置方式3

在index.js

import {
  BrowserRouter,
  HashRouter as Router,
} from "react-router-dom";
const RootApp = ()=>{
    const router = [
       { path:'/' ,
         element: <Layout /> ,
         children:[
          {
            path: "index",
            element: <Home />
          },
          {
              path: "list",
              element: <List />,
          },
          {
           path: '/',
           element: <Navigate to='home'></Navigate> //重定向配置
       },
        ]
      },

    ]
    const element = useRoutes(router);
    return element;
}
const root = ReactDOM.createRoot(document.getElementById('root'));
//使用Router来加载路由对象
root.render( <Router><RootApp></RootApp></Router>)

路由的跳转

页面之间的跳转

  • 类似于Vue
  • 声明式导航
import { Link } from 'react-router-dom'

<!--  普通跳转 -->
  <Link to="要跳转的页面的path"> 文字提示</Link>

<!--  替换跳转  -->
  <Link to="要跳转的页面的path" replace> 文字提示</Link>

<!--  跳转会触发整个页面的重新加载(跳转之后刷新) -->
  <Link to="要跳转的页面的path" reloadDocument> 文字提示</Link>

使用hook来实现 编程式导航 仅支持函数式组件

  • 编程式导航
import { useNavigate } from 'react-router-dom'

 const navigate = useNavigate();

navigate('/list')  // 普通跳转  
navigate('/list',{ replace:true })  // 替换跳转

视图出口

  • 类似于Vue <Router-View />
import { Link, Outlet } from 'react-router-dom'

<div className="ct">
      {/* 子路由渲染的内容 */}
      {/* Outlet会挂载当前路由匹配路径的子路由 */}
      <Outlet></Outlet>
</div>

参数的获取

  • 这里是基于函数组件的获取参数。类组件不能使用hook

useLocation

获取query

  • 通过useLocation可以获取一个url信息的对象 当中包含有一个search ==> ?后的传参(query传参)。通过原生js URLSearchParams来处理这个字符串来获取参数。
const New = () => {
    //location 包含一个search 得到query参数
    const location = useLocation()
    
    //通过原生JS URLSearchParams()
    const searchParams = new URLSearchParams(location.search)
    
    useEffect(() => {
        console.log('location', location);
        console.log('sp', searchParams.entries);

        const a = searchParams.get('a')
        const b = searchParams.get('b')
        console.log('a', a);
        console.log('b', b);
    }, [])

获取state

  • useLocation 得到的location 也会得到跳转的时候传递的 state参数 
  • state参数 可以传递原生的js的数据类型
  • state参数一定是在页面之间跳转的时候进行传递的。新打开的时候是获取不到的。(确认一些参数如果是持续存在的 尽量不要使用state来传递)
<Link to='/new/555?a=1&b=2' replace state={{ k: 1, f: 2, j: true, g: [1, 2, 3], l: { o: 2 } }}>to new</Link>

useSearchParams

  • 它与useLocation功能相似,就是比useLocation多执行了两步,把useLocation得到的search传入URLSearchParams(),并且返回一个URLSearchParams对象,我们就可以调用里面的方法,完成我们业务需求
const New = () => {
    const [query, setQuery] = useSearchParams()
        useEffect(() => {
            console.log('query',query);
        
            const a = query.get('a')
            const b = query.get('b')
            console.log('a', a);
            console.log('b', b);
        }, [])
     }

自定义hook

  • 考虑到以后业务当中多次使用,进行封装
import { useLocation } from "react-router-dom";

export const useQuery = ()=>{
    const location = useLocation()
    const searchParams = new URLSearchParams(location.search)
    const newObj = {}
        for (let [key, value] in searchParams.entries) {
            newObj[key] = value
        }
    return newObj 
    //最终是返回query方式传参的参数 以{key:value}形式返回
}

useParams

获取params

  • 用于获取传递的params参数
const New = () => {
    const params = useParams()
        useEffect(() => {
            console.log('queryObj', queryObj);
            console.log('params', params);
        }, [])
     }

类组件获取查询参数

  • 这里利用的是高阶组件的特性,对属性进行劫持,也就是在使用传入组件的同时携带一些新参数,并且以新组件的形式返回
  • 高阶组件:是一个函数,参数是传入一个组件,并且返回一个新的组件
import { useLocation,useSearchParams ,useParams  }  from "react-router-dom";
//上一个自定义hook
import { useQuery } from "./qf";
const withRouter = (Cp)=>{
     //高阶组件是函数不能使用hook
     
    // 返回一个函数组件
    return (props)=>{
        // 利用函数组件可以使用 hooks的特性 先通过react-router-dom中
        // 的useLocation 来获取location对象
        const location = useLocation();
        const params = useParams();
        const query = useQuery()
        return ( <Cp 
                    location={location} 
                    params={params} 
                    query={query} 
                   //{...props} 让原来组件保持原有的属性
                    {...props} />)
    }
    
}

// 通过withRouter来包裹组件 从而通过这个HOC可以让 类组件获取路由信息
export default withRouter

参数的传递

params参数

  • 需要在路由表当中进行配置,例如:
{
        path: 'new/:id',
        element: <New />
      },

query参数

  • 查询参数只需在跳转的时候,在url后面以 ?key=val&key1=val1 进行拼接