React(函数式组件、jsx、hook、脚手架、路由、组件库)

React

写在前面

  1. 这是我学习完react,并用react做了四个小项目之后进行的总结与复盘,很多东西都只是简单地提一嘴,并不会深入地分析,有不妥之处请多多指教
  2. 现在react提倡使用函数式组件,并且由于我对于类不熟悉,学习react的时候对类组件编程不太上心,因此我下面说的大部分都是基于函数式组件的
  3. hook(用在函数式组件里面的)我说到的的只有几个我自己比较熟悉的以及常用的(useState,useEffect,useLocation,useRoutes ),其他的还有useReducer,useContext,useRef,useRef,useMemo,useLayoutEffect以及自定义hook
  4. 我下面的代码都是建立在脚手架上面的
  5. 新手上路~~~

React是什么 React的特点

  1. react是一个将数据渲染为HTML视图的开源JavaScript库
  2. React使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互(我们在使用react的过程中,可以不操作真实DOM就不要)
  3. react提倡将功能函数内联在html代码中

jsx

  1. jsx语法的代码使用来编写组件的,也可以说是用来写html代码的,然后在html代码中嵌入功能函数
  2. 语法规则:
    标签中混入JS表达式的时候要用{}将js代码包起来
    jsx中只有一个根标签
    jsx中标签必须闭合
  3. 注意:区分“js语句”和“js表达式”
    js表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方,a、a+b、arr.map()、function test(){ }等
    js语句:if(){ }、for(){ }等

state

  1. 状态:每一次状态的改变都会影响到整一个组件,包括子组件,比如说在代码的最后面修改了状态,在前面用到这个状态的逻辑也会执行一遍(实际上是每次状态改变都会从头“执行”一遍我们的代码)

  2. state初始化:
    使用useState进行初始化。
    形式如下:const [yourState,setYourState]=useState(‘’)
    yourState是你自己的state的名字,setYourState是用于改变state的,useState括号里面是state的初始值

  3. 改变state的值:state的值是不可以用普通方式改变的,改变state的值只能通过声明state时候的setYourState

  4. 具体实例:

import React,{ useState } from 'react'
// state初始化
const [allFrames,setAllFrames]=useState(1);
const [file,setFile]=useState(null);
const [isModalVisible, setIsModalVisible] = useState(false);

// 改变state
setFile(file);
setAllFrames(allFrames + 1);

props

  1. props主要用于父组件向子组件传递信息 以及路由跳转组件的时候传递信息
  2. 具体用例:
// 父组件文件
import React from 'react';
export default function AlExe() {
  return (
  	<MySelect option={['true','false']}/>
  )
}
// 子组件文件
import { Select } from 'antd';
import React from 'react';

// props可以在子组件中直接获取直接使用 但是要先在函数的参数位置放上去
export default function MySelect(props) {
	console.log('props ->',props);
  return (
  	<div>MySelect</div>
  )
}

useEffect

  1. 第一个参数接收一个函数,在组件更新的时候执行,函数返回值是一个函数
  2. 第二个参数接收一个数组,用来表示需要追踪的变量,依赖列表,只有依赖更新的时候才会更新内容;没有依赖的时候就进入时执行一次(但是经常会有进入时执行两遍的情况??)
import React,{ useEffect,useState } from 'react';
export default function Test() {

	const [count,setCount]=useState(0);

	function handleClick(){
		setCount(count + 1);
	}
	
	useEffect(() => {
	    console.log('[count]被调用了');
	}, [count])
	
	useEffect(() => {
	    console.log('[]被调用了');
	}, [])
	
  return (
  	<div onClick={handleClick}>Test</div>
  )
}

函数柯里化与高阶函数

  1. 函数柯里化:通过函数调用继续返回函数的方式,实现多次接受参数最后统一处理的函数编码方式
  2. 高阶函数:如果一个函数符合下面2个规范的任何一个,那该函数就是高阶函数
    若A函数,接受的参数是一个函数,那么A就可以称之为高阶函数
    若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
    不用柯里化的可以直接箭头函数返回一个函数的调用
function handleBlur(e){
	console.log(e.target.value);
}
// 涉及到函数的闭包 还有点模糊
// 调用箭头函数 传参Event给箭头函数 Event再传给handleBlur并返回handleBlur的调用
<input onBlur=((Event)=>{handleBlur(Event)}>
// 函数声明
function handleDetail(value){
	console.log(value);
}
// 这两个不能直接用的哈 只是演示一下这样的传参方式
{
	arr.map(i => {
   		return ({
   			// 使用箭头函数传参 调用箭头函数 返回一个函数的调用
   			// 这里的参数是直接传给handleDtail函数的
      		<a onClick={() => handleDetail(i)}>详细信息</a>
   		})
	});
}

生命周期

  1. 生命周期我目前用得不多
    React(函数式组件、jsx、hook、脚手架、路由、组件库)_第1张图片

Diffing算法

  1. Diffing算法对比的最小力度是标签,就是说标签里面的文本是不对比的
  2. key是虚拟DOM对象的标识,在更新时key起着及其重要的作用
  3. 当状态中的数据发生变化的时候,react会根据“新数据”生成“新的虚拟DOM”,随后react进行新旧虚拟DOM的diff比较(比较key),决定是否生成生成/替换真实DOM
  4. 选择key,最好使用每条数据的唯一标识作为key(不变的)

脚手架

  1. 我一般用VSCode的终端来执行命令 电脑命令行也是可以的
  2. 我一般用npm来执行命令的 用yard也是可以的
  3. 全局安装脚手架 这个只要安装过一次就好了
$ npm i-g create-react-app
  1. 切换到想创建项目的目录 下面的hello-react是项目名 你自己决定
$ create-react-app hello-react
  1. 启动项目 记住一定要进入项目文件夹再启动项目
    我遇到过的一个坑是创建完项目就立即启动项目 结果就报错了 !!
    应该先进入项目文件夹 创建完项目之后并不会帮你自动进入到项目文件夹的
$ npm start
  1. 项目打包 项目打包后才可以部署到服务器上面
$ npm run build

redux

  1. redux在小项目中可能用不到,但是在大项目中会用得到,目前还没有做过大项目 ,因此redux目前我不熟,就先不展开了
  2. redux是用来在组件间通信的

路由(下面写的是React Router 6)

react-router-dom

  1. react-router-dom是react中的一个库
  2. 基本项目中都会用到,但是需要手动安装
$ npm i react-router-dom

内置路由

  1. < BrowserRouter > 路由 一般不用这个 哈希路由相对来说好用点
  2. < HashRouter > 哈希路由 使用这个路径上面会有一个# 一般用这个
  3. < Router >
  4. < Redirect >
  5. < Link >
  6. < NavLink >
  7. < Routers >

路由的固定结构

路由定位

  1. element用于放置由路由导进来的组件,不然路径是会改变,但是组件并不会出现
import React from 'react';
import { useRoutes } from 'react-router-dom'
import routes from './routes'
import Head from './component/head';

export default function App() {
    const element = useRoutes(routes);
    return (
        <div>
            <Head />
            {element}
        </div>
    )
}

路由包裹

  1. src文件夹下的index.js文件中
  2. 用< HashRouter >或者< BrowserRouter >将组件包裹起来路由才能发挥作用
  3. 一般项目开发中,直接包裹最外面的那个组件(< App/ >),我一般用< HashRouter >,虽然路径看起来没有那么清爽,但是功能更加强大,< HashRouter >本质是锚点?
import React from 'react'
import  ReactDOM  from 'react-dom/client'
import App from './App'
import { HashRouter } from 'react-router-dom';

root.render(
  <React.StrictMode>
    <HashRouter><App /></HashRouter> 
  </React.StrictMode>
);

路由表

  1. 路由表一般放在routes文件夹里面,命名为index.js
  2. 一般都将路由统一在路由表里面配置
import React from 'react'
import { Navigate } from 'react-router-dom'

import Dlzc from '../pages/logandreg'
import Adminl from '../component/adminl'
import Register from '../component/register'
import ManageUser from '../pages/manageUser'

const routes = [
    {
    	// 以及路由的路径是带'/'的 意义是‘当前路径下’?
        path: '/dlzc',
        element: <Dlzc />,
        children: [
        	// 二级路由(嵌套路由)是不带'/'的 意义是'从头开始查找'?
            {
                path: 'namel',
                element:<Namel/>,
            },
            {
                path: 'register',
                element:<Register/>
            },
            {
                path: '',
                element: <Navigate to='namel' />
            }
        ]
    },
    {
        path: '/manageUser',
        element: <ManageUser />,
    },
    // 这样做的意义是默认导向 Navigate用于重定向
    {
        path: '',
        element: <Navigate to='ManageUser'>
    }
]
 export default routes 

子路由

  1. 一级路由出现的地方是{element}, 子路由(嵌套路由)出现的地方是
  2. 如果没有< Outlet/ >,触发路由之后路径是会改变,但是组件不会出现
import React from 'react'
// 导出Outlet
import { Outlet } from 'react-router-dom'

export default function Dlzc() {
    return (
        <div>
            <Outlet />
        </div>
    )
}

Link和NavLink

  1. Link和NavLink的区别:两者的区别在于NavLink在点击时会有自带的active属性
  2. 前提:
    路由事先在路由表中注册好
    {element}或者< Outlet/ >已经放好了
  3. 具体使用:
<NavLink to='namel'>用户登录</NavLink>
<Link to='register'>用户注册</Link>

重定向:useNavigate与useLocation(这两个是hook,用于函数式组件的)

  1. 前提:
    路由事先在路由表中注册好
    {element}或者< Outlet/ >已经放好了
// LogPack文件夹中的index.jsx
import React from 'react'
// 1. 导出useNavigate
import { useNavigate } from 'react-router-dom';

export default function LogPack() {

	// 2. 定义navigate
  	const navigate = useNavigate();
  	const data=[{name:'kkt',age:18},{name:'xiaoming',age:18}];

  	function handleDetail() {
  		// 使用navigate进行重定向 state用于传递参数
  	  	navigate('/logdetail', { state: data});
  	}
 
  return (
  	// 点击这个链接 调用了handleDetail函数 重定向至另一个组件(将当前组件换成了另一个组件)
  	// 组件的放置的位置仍然是{element}
	<a onClick={handleDetail}>详细信息</a>
  )
}
// LogDetail文件夹中的index.jsx
import React from 'react'
// 1. 导入useLocation
import { useLocation } from 'react-router-dom'

export default function LogDetail() {

	// 2. useLocation().state就是传过来的数据 state是键
    console.log(useLocation().state);

    return (
    	<div>logDetail</div>
    )
}

组件库

  1. antd是一个很好用的组件库,有很多小组件实用性都较好,表格也做得不错,文档页写得不错自己也可以对antd的组件进行封装,提高代码的复用率,附上antd传送门
  2. antV主要用于数据的可视化,文档写得不错,附上antV传送门
  3. echarts是一个图表库,功能很强大,文档个人认为有点难懂,附上ECharts传送门,想要使用基于ECharts基于react的封装,得走这里,这个是ECharts的react封装的一个库,在github上面的

注意

  1. '…'运算符(展开运算符)
    展开运算符很好用,包括在对象中、数组中,在很多地方都是可以用到展开运算符的。
    展开运算符用于展开一个可迭代对象(比如数组…arr),或者{…data},data是一个对象,这样的用法相当于浅复制一个对象
  2. JavaScript中的众多方法,特别是数组的很多方法在react中都是很有必要的
  3. ES6在react中也得用得相当顺手
  4. 一般组件文件夹以组件名来命名,而组件文件均以index.jsx命名

你可能感兴趣的:(react,前端,react.js,javascript,前端)