react 的知识点总结

react特点

  1. 声明式编码,通过一些行为替代,例如语法糖
  2. 组件化编码,提高开发效率及组件复用率,js是命令式编码,通过获取->操作等步骤
  3. React Native 编写原生应用
  4. 高效(优秀的Diffing算法),通过虚拟DOM和优秀的diff算法,尽量减少与真实DOM的交互

创建react项目

npm create-react-app myapp

创建完毕之后,根据需要删除文件以及组件代码,例如:

App.css、App.test.js、index.css、logo.svg、reportWebvitals.js、setupTests.js等文件

index.js

index.js:删除多与代码,仅保留如下代码:

importReactfrom'react';
importReactDOMfrom'react-dom';
importAppfrom'./App';

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

app.js

改名为 app.jsx ,并修改代码为:

exportdefaultfunctionApp() {
  return (
    <div className="App">
    
    </div>
  );
}

配置路由文件

安装react-router-dom

npm install react-router-dom

基础使用

在app.jsx中

import React from 'react'
import { Link, BrowserRouter, Route, Routes } from 'react-router-dom'
import Home from './views/Home'
import About from './views/About'
export default function App() {

  return (
    <BrowserRouter>
      <Link to="/home">Home</Link>
      <Link to="/about">About</Link>
      <Routes>
        <Route path='/home' element={<Home></Home>}></Route>
        <Route path='/about' element={<About></About>}></Route>
      </Routes>
    </BrowserRouter>
  );
}

(PS:这里有个小技巧,BrowserRouter需要在每一个页面中使用,所以可以在index.js中:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {BrowserRouter} from 'react-router-dom'
ReactDOM.render(
  <BrowserRouter><App /></BrowserRouter>,
  document.getElementById('root')
);

NavLink

<NavLink>是一种特殊的 <Link>,知道它是否“活跃”。 这在构建导航菜单(如面包屑或一组选项卡)时很有用,您希望在其中显示当前选择了哪些选项卡;

只需要将原来的Link变成NavLink即可

{/* NavLink 默认添加active,可以通过函数传递给className*/}
<NavLink className={({ isActive }) => isActive ? 'now' : '' } to="/home">Home</NavLink>
<NavLink className={({ isActive }) => isActive ? 'now' : '' } to="/about">About</NavLink>

重定向

引入Navigate,并修改以下代码

<Routes>
   <Route path="/about" element={<About></ About >} />
   <Route path="/home" element={<Home></Home>} />
   {/* 重定向,当匹配不到路由时重定向至home */}
   <Route path="*" element={<Navigate to="/home" replace={true} />} />
</Routes>

嵌套路由

index页面:

import React from 'react'
import { NavLink, Outlet } from 'react-router-dom'

export default function Home() {
  return (
    <div>
      <NavLink to="/home/first">first</NavLink> |
      <NavLink to="/home/second">second</NavLink>
      {/* 嵌套路由出口 */}
      <Outlet></Outlet>
    </div>
  )
}

App.jsx页面:

export default function App() {

  return (
    <div>
      <NavLink to="/home">Home</NavLink>
      <NavLink to="/about">About</NavLink>
      <Routes>
        <Route path='/home' element={<Home></Home>}>
          <Route path='/home/' element={<First></First>}></Route>
			{/* 在V6版本中允许相对路径写法 */}
          <Route path='second' element={<Second></Second>}></Route>
        </Route>
        <Route path='/about' element={<About></About>}></Route>
        <Route path="*" element={<Navigate to="/home" replace={true} />} />
      </Routes>
    </div>
  );
}

useRoutes

useRoutes钩子在功能上等同于<Routes>,但它使用JavaScript对象而不是<Route>元素来定义路由。这些对象具有与普通<Route>元素相同的属性

在src中新建router/index.js:

import { Navigate } from 'react-router-dom'
import Home from '../views/Home'
import About from '../views/About'
import First from '../views/Home/First'
import Second from '../views/Home/Second'

let routers = [
    {
        path: '/home',
        element: <Home></Home>,
        children: [
            {
                path: '/home/',
                element: <First></First>,
            },
            {
                path: '/home/second',
                element: <Second></Second>,
            }
        ]
    },
    {
        path: '/about',
        element: <About></About>
    },
    {
        path: '*',
        element: <Navigate to="/home" replace={true} ></Navigate>
    }
]

export default routers;

App.js:

import React from 'react'
import { NavLink, useRoutes } from 'react-router-dom'
import router from './router'
import "./App.css"
export default function App() {
  let routers = useRoutes(router)
  return (
    <div>
      <NavLink to="/home">Home</NavLink>
      <NavLink to="/about">About</NavLink>
      {routers}
    </div>
  );
}

路由传参

params传参

配置路由

path: '/about/:id',

跳转

<NavLink to="/about/1">About</NavLink>

页面获取:

import React from 'react'
import { useParams} from 'react-router-dom';
export default function About(props) {
    let { id } = useParams()
    console.log(id);
    return (
        <div>About</div>
    )
}

search传参

跳转

<NavLink to="/about?id=1">About</NavLink>

获取

import React from 'react'
import { useSearchParams } from 'react-router-dom';
export default function About(props) {
    let [search] = useSearchParams()
    let id = search.get('id');
    return (
        <div>About</div>
    )
}

state传参

跳转:

<NavLink to="/about" state={{ id: 1 }}>About</NavLink>

获取

import React from 'react'
import {useLocation} from 'react-router-dom';
export default function About(props) {
    let {state:{id}} = useLocation()
    console.log(id);
    return (
        <div>About</div>
    )
}

编程式路由

useNavigate钩子返回一个函数,允许您以编程方式进行导航

let navigate = useNavigate()
  function jump() {
    navigate('/about',{
      replace: true,
      state: {
        id: 1
      }
    })
  }

导航函数有两个签名:

  1. 传递一个To值(与的类型相同)和一个可选的second {replace, state}
  2. 或在历史堆栈中传递你想要的增量。例如,navigate(-1)相当于点击后退按钮。

页面开发

创建虚拟dom

js方式

<body>
    <!-- 1.准备一个容器,做为作用域 -->
    <div id="test"></div>
    <!-- 引入js文件,注意顺序 -->
    <!-- 引入react核心库 -->
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入用于支持react操作dom的扩展 -->
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script>
        // 1.创建虚拟dom
        const VDOM = React.createElement('h1', {
            id: 'test',
            className: 'cla',
            onClick() {
                alert('hello')
                // 绑定事件
            }
        }, 'hello') // 标签名,标签属性(class需要改为className),标签内容
        // const VDOM = React.createElement('h1', {
        //     id: 'ttt',
        //     class: 'uuuu'
        // }, React.createElement('span', {}, 'hello')) // 多个标签嵌套的写法,繁琐,应该使用jsx
        // 2.渲染虚拟dom到页面
        ReactDOM.render(VDOM, document.getElementById('test')) // 两个参数:虚拟dom,容器
    </script>
</body>

jsx方式

<body>
     <!-- 1.准备一个容器,做为作用域 -->
     <div id="test"></div>
     <!-- 引入js文件,注意顺序 -->
     <!-- 引入react核心库 -->
     <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
     <!-- 引入用于支持react操作dom的扩展 -->
     <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
     <!-- 引入babel,用于将jsx转换成js -->
     <script src="../js/babel.min.js"></script>
     <script type="text/babel">// 表示这里面写的是jsx,通过babel进行编译,一定要写
        // 1.创建虚拟dom
        // const VDOM = <h1>hello</h1>  // 此处一定不要写引号,不是字符串,jsx的写法
        const VDOM = (// 多层嵌套的写法,但需要babel翻译,翻译后的代码React.createElement('h1',{},React.createElement('span',{},'hello'))
            <h1>
                <span>hello</span>
            </h1>
        )
        // 2.渲染虚拟dom到页面
        ReactDOM.render(VDOM, document.getElementById('test'))// 两个参数:虚拟dom,容器
     </script>
</body>

数据请求

首先:安装axios :npm install axios;

然后:

axios({
  url:'地址',
  params:{
    
  }
}).then((res)=>{
  console.log(res.data)
}).catch((error)=>{
  console.log(error)
})

变量定义

  1. state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
  2. 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)
  3. 用来给组件提供组件内部使用的数据

注意!!!

  1. 只有通过class创建的组件才具有状态
  2. 组件中render方法中的this为组件实例对象
  3. 组件自定义的方法中this为undefined,如何解决?
    强制绑定this: 通过函数对象的bind()
    箭头函数+赋值语句
  4. 状态数据,不能直接修改或更新,必须使用setState()
  5. 状态是私有的,完全由组件来控制
  6. 不要在 state 中添加 render() 方法中不需要的数据,会影响渲染性能!
    可以将组件内部使用但是不渲染在视图中的内容,直接添加给 this
  7. 不要在 render() 方法中调用 setState() 方法来修改state的值
    但是可以通过 this.state.name = 'rose' 方式设置state(不推荐!!!!)

配置代理

在src中,新建setupProxy.js(必须是这个名字,react脚手架会识别),在文件中写以下配置内容(最近的项目要使用高版本这个,不然会导致项目无法启动):
http-proxy-middleware高版本(2以上):

const proxy = require('http-proxy-middleware')//引入http-proxy-middleware,react脚手架已经安装

module.exports = function(app){
	app.use(
		proxy.createProxyMiddleware('/api',{ //遇见/api1前缀的请求,就会触发该代理配置
			target:'http://localhost:5000', //请求转发给谁
			changeOrigin:true,//控制服务器收到的请求头中Host的值
			pathRewrite:{'^/api':''} //重写请求路径,下面有示例解释
		}),
		proxy.createProxyMiddleware('/api2',{
			target:'http://localhost:5001',
			changeOrigin:true,
			pathRewrite:{'^/api2':''}
		}),
	)
}

http-proxy-middleware低版本(2以下):

const proxy = require('http-proxy-middleware')//引入http-proxy-middleware,react脚手架已经安装

module.exports = function(app){
	app.use(
		proxy('/api',{ //遇见/api1前缀的请求,就会触发该代理配置
			target:'http://localhost:5000', //请求转发给谁
			changeOrigin:true,//控制服务器收到的请求头中Host的值
			pathRewrite:{'^/api':''} //重写请求路径,下面有示例解释
		}),
		proxy('/api2',{
			target:'http://localhost:5001',
			changeOrigin:true,
			pathRewrite:{'^/api2':''}
		}),
	)
}

写好以后,重启项目!!!
然后进行请求

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值