JavaScript-React-2

React
三大API
React.createElement()
用来创建React元素,无法修改React.createRoot()
用来创建React的根容器, 容器用来放置React元素root.render()
当首次调用时, 容器节点里的所有DOM元素都会被替换, 后续的调用则会使用React的DOM差分算法(DOM diffing alorithm) 进行高效更新
不会修改容器节点(只会修改容器的子节点), 可以在不覆盖现有子节点的情况下, 将组件插入已有的DOM节点中
JSX
注意事项:
JSX不是字符串, 不要加引号
JSX中html标签应该小写, React组件应该大写开头
JSX中有且只有一个根标签
jSX的标签必须正确结束
<input type='text' />
必须写斜杠或成对出现在JSX中可以使用{}嵌入表达式
- 有返回值就是表达式
如果表达式是空值, Null, undefined, 布尔值, 不会显示
在JSX中, 属性可以直接在标签中设置
class 需使用className代替
style中必须使用对象设置, 不能使用属性
1
const div = <div style={{backgroundColor:'yellow'}}></div>
特性
1 | const arr = ['1', '2', '3'] |
相当于直接渲染列表中的所有元素
1 | const list = <ul>data.map(item => <li>{item}</li>)</ul> |
虚拟DOM
好处:
降低API的复杂度
解决兼容问题
提升性能(减少DOM的不必要操作)
当我们在JSX中显示数组时, 数组中每一个元素都需要一个唯一的KEY, 否则会显示警告
JSX比较元素是否发生改变是按照位置比较的,如果将一个新元素插入到数组前,则可能造成重复元素渲染, 为了解决这个问题, 可以自定义唯一KEY, 将比较规则改成用KEY比较
1 | <ul> |
尽量不要使用索引做KEY, 索引会跟着元素顺序改变, 做无用功. 唯一不同就是无警告
React 项目
public/index.html 是首页的模板; webpack会以index.html为模板生成index.html
src/index.js 是js的入口文件
手动准备
npm init -y
初始化
npm install react react-dom react-scripts -S
下载依赖
需要使用import ReactDOM from 'react-dom/client';
引入ReactDOM
npx react-scripts build
打包
npx react-scripts start
开发时测试
这两个命令可以在packetage.json中加入’scripts’内置:
"start": "react-scripts start"
命令行中使用npm start
"build": "react-scripts build"
命令行中使用npm run build
ESLint语法检查器:
可以在packetage.json 中添加:
1
2
3
4
5"eslintConfig": {
"extends": [
"react-app"
]
}
引入CSSimport './index.css'
React组件
函数组件(推荐)
1 | function App(){// 也可以使用箭头函数 |
事件
在React中事件需要通过元素的属性来设置,和原生Js不一样, 在React中事件的属性需要使用驼峰命名法
onclick -> onClick
onchange -> onChange
属性值不能直接执行代码:
1 | onClink = {() => {alert('123')}} // 正确 |
事件对象
React事件中同样会传递事件对象, 可以在响应函数中定义参数来接收事件对象
React事件对象不是原生的事件对象,是经过React包装过的事件对象
取消行为:
1 | const clickHandler = (event) => { |
动态传参
在组件间,父组件可以通过props(属性)向子组件传递数据(父传子)
- props(外部,父 -> 子)是只读属性, 不能修改
1 | <LogItem test='123' /> |
状态
在React中,当组件渲染完毕后,在修改组件中的变量,不会使组件重新渲染。因此必须重新渲染。
state(自身)
1
2
3
4
5
6
7import { useState } from 'react'
const LogItem = () => {
const [count, setCounter] = useState(1)
// 该函数会返回一个数组,数组第一个元素是初始值,第二个是一个函数
// 初始值只是用来显示,修改不会触发渲染
// 函数通常命名为setXxxx, 使用函数可以修改count触发渲染
}React会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染
在函数组件中,我们需要通过钩子函数,获取state(useState)
State实际就是一个被React管理的变量
setXxxx只有在值与count不一样的时候才会渲染
当通过setState去修改一个state时,并不是修改当前state,是修改下一次渲染时的state时
setState()会触发组件的渲染,他是异步的,所以当调用setState需要用到旧值,可能出现错误。可以传递回调函数来修改state
1
2setCounter(prevCounter => prevCounter + 1)
// 回调函数执行时,React会将最新的state值作为参数
注意
当useState为一个对象时,如果直接修改旧的State对象,对象地址不会改变,所以不会被渲染。可以使用浅拷贝
PS: setXxxx({...user, name:'aaa'})
useRef()钩子函数
创建一个容器, 返回一个普通的JS对象,但是可以确保每次渲染都是同一个对象,减少对象的创建次数(当你需要一个对象不会因为渲染改变时使用)
类组件
必须继承React.Component
1 | class App extends React.Component{ |
类组件的props是存储在实例对象中,可以直接通过实例对象访问
this.props
类组件的state是存储在对象的state属性中,可以直接通过
this.state
访问通过
this.setState()对其进行修改
当我们通过this.setState()修改state时,只会修改设置的属性(只限于直接存储state的值)
1 | state = { |
- 在类组件中,响应函数是以类的方法定义的
1 | clickHandler = () => { |
createRef钩子函数
与useRef相同,都是创建一个不会变化的JS容器
- 标题: JavaScript-React-2
- 作者: IntYou
- 创建于: 2023-03-08 14:43:21
- 更新于: 2023-03-08 21:21:43
- 链接: https://intyou.netlify.app/2023/03/08/JavaScript-React-2/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。