React初级知识点汇总(笔记)

本文详细介绍了React的环境配置、ReactDOM渲染、JSX语法、组件与元素、属性传递、事件处理、条件渲染以及自定义组件。还涵盖了React状态管理、生命周期方法、Ref的使用、Portal功能以及React Router Dom的基本概念和应用场景。通过对这些知识点的深入理解,读者将能够更好地掌握React开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

## 环境

创建环境
npx create-react-app project_name

启动
npm start / yarn start
npm run build

弹出设置
npm run eject

安装个别包
npm i moudle_name --save
yarn add module_name
npm i module_name --save-dev
yarn add -D module_name

初始安装
npm i
yarn

## React/ReactDOM

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

JSX是什么?
React.createElement的语法糖
JSX <-- --> React.createElement转换关系

Babel编译工具

<A props1={1} props2="2">
  <B>abc<B>
  <C />
</A>

React.createElement(组件对象, {props1, props2}, ...children)

组件和元素
A    <A />

JSX表达式的写法

{表达式}
表达式只能写一句语句,不能写if / for / while
可以写的:变量,常量,函数调用

<A>{表达式}</A>

children位置:
数字/字符串/数组(数字,字符串)
布尔类型/null/undefined/Symbol
不能写object在children位置

<A props1={表达式} />
<A name={'abc'} age={12} />

表达式输出数组
<A>{items.map((item, index) => <B key={index}>{item.name}</B>)}</A>

items = [<B key='b'>1</B>, <C key='c'>2</C>, <D key='d'>3</D>]
<A>{items}</A>

HTML元素的属性
<br/> <a></a> 符合JSX语法,Xml标签必须闭合

HTML转JSX

html里属性全是小写,JSX里属性要符合驼峰 colspan --> colSpan, autoplay --> autoPlay

特殊:class --> className, for --> htmlFor
值:
style='width: 120px; font-size: 1em'
style={{width: 120, fontSize: '1em'}}

有JSX为HTML添加的属性
defaultValue

事件
onclick='alert(1)'
onClick={() => {}}
this.handleClick.bind(this)
onClick={this.handleClick}

条件渲染
三目运算符: 条件? 真 : 假
开关:条件 && <元素 />

JSX注释
<A>
  //<B /> 错
  {/* <B />*/}
  <C
    {/*props="c"*/} 错
    // props1=‘123’
  >
</A>

自定义组件

组件名字:首字母大写

<link />
<Link />

obj.a = function() { return <div />}

<obj.a />

class组件 类组件
function组件 函数组件 无状态组件

区别:1 类组件有状态,函数组件没有状态 2 类组件有生命周期函数,函数组件没有

class A extends React.Component {
  constructor(props) {
    super(props)
    ...
  }
  render() {
    return null
  }
}

props: this.props.属性名
state
定义:state做什么的--内部状态,state是object
初始化:构造方法/成员的声明部分,不应在其他成员函数里给state赋值

class A {
  state = {count: 0}
  constructor(props) {
    super(props)
    this.state = {count: 0}
  }
  componentDidMount() {
    this.state = {count: 0} //错
  }
}

改变state值,通过 this.setState
执行this.setState后会render(this.render方法从来不会主动调用)
this.setState的效果是异步的(this.state不会在setState后马上改变)
this.setState(updater, callback)
updater:
1. object:是state的object内容一部分
state = {a: 1, b: 2}
this.setState({b: 3}) --> 把{a: 1, b: 2}和{b: 3}合并
Object.assign({a: 1, b: 2}, {b: 3}) --> {a:1, b:3}
this.setState({c:5}) --> {a:1, b:3, c:5}

state = {a: [1,2,3], b: {name: 'zhangsan', age: 20}}
不要这样操作:
this.state.a.push(4)
this.setState({a: this.state.a})
this.state.b.age = 21
this.setState({b: this.state.b})

推荐方式(浅拷贝后setState):
this.setState({a: [...this.state.a, 4]})
this.setState({a: this.state.a.concat(4)})
this.setState({b: {...this.state.b, age: 21}})
this.setState({b: Object.assign({}, this.state.b, {age: 21})})

注意情况
state = {a:1, b:2}
this.setState({a: 10})
this.setState({b: 20})
Object.assign({}, this.state, {a:10}, {b:20})

state = {a:1, b:2}
this.setState({a: 10}) // 无效
this.setState({a: 20})
Object.assign({}, this.state, {a:10}, {a:20})

2. 函数形式 (state, props) => 部分state object
state = {count: 0}
// 错
this.setState({count: this.state.count + 1})
this.setState({count: this.state.count + 1})
Object.assign({}, this.state, {count: this.state.count + 1},{count: this.state.count + 1})
state = {count: 1}
// 对
this.setState((state) => ({count: state.count + 1}))
this.setState((state) => ({count: state.count + 1}))
state = {count: 2}

setState第二个参数callback,参数可选
() => {
  // render之后执行的内容
  // 认为跟componentDidUpdate执行的时间一致
}

生命周期:
三个阶段

挂载
  **constructor** 初始化state和其他变量
  static getDerivedStateFromProps
  **render** 一定会执行,不要做跟render无关事情(例如发起异步请求)
  **componentDidMount** 有副作用的操作(绑定全局事件,启动计时器,发起ajax请求)
更新
  static getDerivedStateFromProps
  shouldComponentUpdate
  **render** 不一定会执行
  getSnapshotBeforeUpdate
  **componentDidUpdate** dom元素真正更新,发起ajax,this.setState有条件使用
卸载
  **componentWillUnmount** 清除副作用

this.forceUpdate() 强制render(),跳过shouldComponentUpdate

## Ref

作用:获得dom元素或者获得JSX元素,不要用原生dom查询方式,比如document.querySelect()

场景:
- 管理焦点,选择文本,播放媒体
- 强制动画
- 集成第三方的dom库

Ref几种方式:
1)class组件里
this.ref = React.createRef()
<A ref={this.ref}>
<video ref={this.ref}>
this.ref.current ...

2)回调函数 (两种组件都可以)
<video ref={(el) => this.ref = el}>
this.ref ...

3)函数组件使用,hook方式
const ref = React.useRef()
<video ref={this.ref}>
ref.current

## Portal
作用:在挂载点之外渲染
场景:对话框,浮层

ReactDOM.createPortal(<元素 />, 挂载点dom)

render() {
  return <div onClick={() => {/*Portal内的点击能冒泡到这里*/}}>...{ReactDOM.createPortal(<元素 />, 挂载点dom)}</div>
}

## React事件

取消默认动作 preventDefault
取消冒泡 stopPropagation
onChange

## React数据传输

- 父传子,通过属性
- 子传父,通过回调函数

<Parent/>
function Parent() {
  const [a, setA] = useState(0)
  return <div><Child prop1={a} onChangeValue={() => setA(10)}/></div>
}

## 函数组件

function Component(props) {
  props.a
}

function Component({a, b, c}) {
  return <div />
}

## 钩子函数Hook

Hook使用规则
1. 只能在函数组件或自定义Hook函数里调用钩子函数
2. 只能在函数的第一层级调用钩子函数(不要在if ,for, while, switch调用)

自定义Hook要求:use开头驼峰,useSearchParams

function useSearchParams() {
  const location = useLocation()
  return location.search
}

React.useState

let [state, setState] = useState(初始值)
setState(updater)
updater: 函数或者其他值

React.useEffect(callback, 依赖关系)

参数
callback
函数内容就是执行副作用
return部分是取消副作用

挂载的时候一定回执行callback,卸载一定会执行return的函数

更新时,先卸载,再执行副作用
依赖关系
undefined,每次都执行
[],从不执行
[a, b] a或b值和上次渲染不同的时候会执行

## React-Router-Dom 5.x

组件三大类
- 路由器 BrowserRouter/HashRouter
- 路由 Switch/Route/Redirect
- 导航 Link/NavLink

函数
- withRouter 转换普通组件成为带路由参数的组件
- 钩子函数
  - useHistory
  - useLocation
  - useRouteMatch
  - useParams

实现无刷新路由的原理
history.pushState/replaceState, window.onpopstate

HashRouter和BrowserRouter区别
在不支持history api的旧浏览器上要使用无刷新路由,或者在不支持路径重写的server环境里

Apache/nginx rewrite
发布单页面应用的时候需要注意什么?
要web server配置url rewrite规则

react-router-dom使用
顶级元素<BrowserRouter> / <HashRouter>

Route
- path - 匹配路径
  - 静态路径
  - 动态路径,参数以:开头,match.params.参数名
    - ? + *
    - 用正则表达式 :参数(正则) 比如 /:id([\d]+)
- 渲染
  - render - 函数
  - children - 函数
  - component - 组件定义
  - 直接JSX写在子元素位置
- exact/strict/sensitive

Switch
内部的子路由元素最靠前匹配的路由会生效,其后的路由被忽略
显示404
<Switch>
  <Route path='...'>
  <Route path='...'>
  <Route path='...'>
  <Route component={NotFoundView}/>
</Switch>

Link
- to
  - 字符串
  - location 可以设置location.state
  - (location) => 新的location
- replace

NavLink
是特殊的Link,可以根据是否匹配当前的路由显示不同的UI

- activeClassName/activeStyle
- className/style 的值可以是回调函数 isActive => 返回className或者style对象
- exact

不要用<a>做跳转
跳转方式

JSX形式:<Redirect >属性基本和Link一样,push
编程形式:history.push / replace,这里history对象是react-router提供的,不是window.history

机试准备

准备一个干净的开发环境

npx create-react-app project-name
cd project-name
code .

// git bash
rm src/*
touch src/index.js

index.js
import 'bootstrap/dist/css/bootstrap.min.css'
ReactDOM.render()

yarn add react-router-dom axios bootstrap

yarn start

导航条界面
```
<ul class="nav justify-content-center nav-tabs">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled">Disabled</a>
  </li>
</ul>
```

左侧导航条

```
<ul class="nav flex-column">
  <li class="nav-item">
    <a class="nav-link active" aria-current="page" href="#">Active</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Link</a>
  </li>
  <li class="nav-item">
    <a class="nav-link disabled">Disabled</a>
  </li>
</ul>
```

占位符
```
<span class="placeholder col-6"></span>
<span class="placeholder w-75"></span>
<span class="placeholder" style="width: 25%;"></span>
```

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值