JavaScript-React-2

IntYou (^_^)

React


三大API

  1. React.createElement()用来创建React元素,无法修改

  2. React.createRoot()用来创建React的根容器, 容器用来放置React元素

  3. root.render()

    • 当首次调用时, 容器节点里的所有DOM元素都会被替换, 后续的调用则会使用React的DOM差分算法(DOM diffing alorithm) 进行高效更新

    • 不会修改容器节点(只会修改容器的子节点), 可以在不覆盖现有子节点的情况下, 将组件插入已有的DOM节点中

JSX

注意事项:
  1. JSX不是字符串, 不要加引号

  2. JSX中html标签应该小写, React组件应该大写开头

  3. JSX中有且只有一个根标签

  4. jSX的标签必须正确结束<input type='text' />必须写斜杠或成对出现

  5. 在JSX中可以使用{}嵌入表达式

    • 有返回值就是表达式
  6. 如果表达式是空值, Null, undefined, 布尔值, 不会显示

  7. 在JSX中, 属性可以直接在标签中设置

    • class 需使用className代替

    • style中必须使用对象设置, 不能使用属性

      1
      const div = <div style={{backgroundColor:'yellow'}}></div>
特性
1
2
const arr = ['1', '2', '3']
const list = <div>{arr}</div>

相当于直接渲染列表中的所有元素

1
const list = <ul>data.map(item => <li>{item}</li>)</ul>

虚拟DOM

好处:

  1. 降低API的复杂度

  2. 解决兼容问题

  3. 提升性能(减少DOM的不必要操作)

当我们在JSX中显示数组时, 数组中每一个元素都需要一个唯一的KEY, 否则会显示警告

JSX比较元素是否发生改变是按照位置比较的,如果将一个新元素插入到数组前,则可能造成重复元素渲染, 为了解决这个问题, 可以自定义唯一KEY, 将比较规则改成用KEY比较

1
2
3
4
<ul>
<li key='1'>1</li>
<li key='3'>2</li>
</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
2
3
4
5
6
function App(){// 也可以使用箭头函数
retun <div>Hello</div>
}

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<App/>)// 一般写在入口文件中
事件

在React中事件需要通过元素的属性来设置,和原生Js不一样, 在React中事件的属性需要使用驼峰命名法

onclick -> onClick

onchange -> onChange

属性值不能直接执行代码:

1
2
onClink = {() => {alert('123')}} // 正确
oClink = {clickHandler} //函数不需要加括号,若返回值为函数可加
  • 事件对象

    • React事件中同样会传递事件对象, 可以在响应函数中定义参数来接收事件对象

    • React事件对象不是原生的事件对象,是经过React包装过的事件对象

取消行为:

1
2
3
4
5
6
const clickHandler = (event) => {
event.preventDefault();
//取消默认行为(PS: 若放在<a href='#'>中,则取消跳转)
event.stopPropagation()
//取消冒泡
}
  • 动态传参

    在组件间,父组件可以通过props(属性)向子组件传递数据(父传子)

    • props(外部,父 -> 子)是只读属性, 不能修改
1
2
3
4
5
6
7
<LogItem test='123' />

const LogItem = (props) => {
// 可以在函数组件的形参中定义一个props,props指定所有传递的参数
return <div>{props.test}</div>
// 调用
}
  • 状态

    在React中,当组件渲染完毕后,在修改组件中的变量,不会使组件重新渲染。因此必须重新渲染。

    • state(自身)

      1
      2
      3
      4
      5
      6
      7
      import { useState } from 'react'
      const LogItem = () => {
      const [count, setCounter] = useState(1)
      // 该函数会返回一个数组,数组第一个元素是初始值,第二个是一个函数
      // 初始值只是用来显示,修改不会触发渲染
      // 函数通常命名为setXxxx, 使用函数可以修改count触发渲染
      }
      1. React会监控这个变量的变化,当state发生变化时,会自动触发组件的重新渲染

      2. 在函数组件中,我们需要通过钩子函数,获取state(useState)

      3. State实际就是一个被React管理的变量

      4. setXxxx只有在值与count不一样的时候才会渲染

      5. 当通过setState去修改一个state时,并不是修改当前state,是修改下一次渲染时的state时

      6. setState()会触发组件的渲染,他是异步的,所以当调用setState需要用到旧值,可能出现错误。可以传递回调函数来修改state

        1
        2
        setCounter(prevCounter => prevCounter + 1)
        // 回调函数执行时,React会将最新的state值作为参数

注意

当useState为一个对象时,如果直接修改旧的State对象,对象地址不会改变,所以不会被渲染。可以使用浅拷贝

PS: setXxxx({...user, name:'aaa'})

  • useRef()钩子函数

    创建一个容器, 返回一个普通的JS对象,但是可以确保每次渲染都是同一个对象,减少对象的创建次数(当你需要一个对象不会因为渲染改变时使用)

类组件

必须继承React.Component

1
2
3
4
5
6
class App extends React.Component{
// 类组件中,必须添加一个render()方法,且方法的返回值要是一个jsx
render(){
return <div>aaa</div>
}
}
  • 类组件的props是存储在实例对象中,可以直接通过实例对象访问this.props

  • 类组件的state是存储在对象的state属性中,可以直接通过this.state访问

    • 通过this.setState()对其进行修改

    • 当我们通过this.setState()修改state时,只会修改设置的属性(只限于直接存储state的值)

1
2
3
4
5
state = {
count: 0
test: 'aaa'
obj: {name: 'aaa'} // 没有直接存储在state,会被覆盖
}
  • 在类组件中,响应函数是以类的方法定义的
1
2
3
4
5
6
7
clickHandler = () => {
this.setState(prevState => {
return {
count: prevState + 1
}
})
}
  • 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 进行许可。
此页目录
JavaScript-React-2