type
status
date
slug
summary
tags
category
icon
password
概念
index.js:
- 项目入口
- react和react-dom/client:项目必要的两个核心包
- 导入项目根组件,将根组件渲染到id为root的节点上,也就是将项目的根组件渲染到public的index.html的id为root的div节点上
JSX
基础语法
JSX:JavaScript+XML(HTML)
:- 表示在JS代码中编写HTML模板结构,是React中编写UI模板的方式
- HTML声明式的模板写法+JS的可编程能力,JSX 会让你把标签放到 JavaScript 中。而大括号会让你 “回到” JavaScript 中
- 本质:JS的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行
- 使用JS表达式:大括号语法,里面仅支持表达式,不支持语句(if、变量声明之类的)
- 组件不能返回多个JSX标签,必须将其包裹到一个共享的父级中,哪怕是用空标签包含:<>内容</>
列表渲染/条件渲染
- 列表渲染:
- 用原生js的map方法
- key值:独一无二的字符串或者number id。是react框架内部使用,用来提升更新性能的
- 提高虚拟dom的更新性能
- 若不设置key,可能触发一些bug:比如说只更新第二行,因为没有key导致其他的元素也更新了,或者最后的结果不是更新,而是做成了多一行其他的
- 为了触发过渡的效果
v-for中key的作用有点像:key属性是dom元素的唯一标识,如果没有这个东西的话,在dom里面添加/删除一个元素就必须整体进行重绘,但如果有了kitemey,重绘之前vue会检查哪些是需要重绘的新元素,如果没有的话就直接用之前的,避免资源浪费。
- 基础条件渲染
- 复杂条件渲染
自定义函数(返回不同JSX模板)+if判断语句
事件绑定
语法:on+事件名称={ 事件处理程序(回调函数) }
获取事件对象:在事件回调函数里面写一个形参
传递自定义参数:箭头函数

组件
一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI,渲染组件就是把组件当成标签书写
使用
class
的方式来创建组件:- this的指向:
- 在类组件中,this指向当前组件实例
- this.props可以访问当前组件的props,而这个props是从父组件传进来的
获取组件的引用
函数形式:
- 当组件挂载完成后,
react
会调用ref
属性里面对应的函数
- react会把这个组件的实例作为参数传给这个函数
- 比如说像表单校验的时候,就可以用这个引用来调用这个组件有的函数/方法:
类组件创建:
- 使用
React.createRef()
创建一个应用
- 通过
ref={this.formRef}
将该引用绑定到表单上
使用useRef创建:类组件不能用Hook
useRef()
是 React Hook,只能在函数组件或自定义 Hook 中使用,不能在类组件中使用,类组件用React.createRef()
创建引用而函数组件用useRef()
原因:函数式组件没有this,没办法用this.form = xxx这种形式来为引用赋值,React 提供了
useRef()
这个 Hook,用于在函数组件中“存储跨渲染的引用”:父子组件通信
单向数据流
react采用的是单向数据流,而不是双向数据绑定,即数据只能从父组件流到子组件:
原因:
- 这种设计模式使得应用程序的结构更加清晰、易于理解和调试。相比之下,双向数据绑定会导致数据流动方向不确定,增加了代码的复杂度和难度
- 在双向数据绑定中,当数据发生变化时,系统需要同时更新视图和数据模型,这会导致性能瓶颈。而在单向数据流中,数据的更新只会从父组件向子组件进行,这样可以避免不必要的视图更新,提高了应用程序的性能表现
- 在双向数据绑定中,由于数据的修改可能来自于多个组件,造成了数据的不可预测性。而在单向数据流中,数据的修改只能由父组件或本身进行,这样可以更好地控制应用程序的逻辑,减少了错误发生的概率
- React支持服务端渲染,这对于SEO和性能都非常重要。在双向数据绑定中,由于数据的修改可能来自于客户端,这使得服务端渲染变得更加困难。而在单向数据流中,由于数据的修改只能来自于服务端或本身,这样可以更方便地实现服务端渲染
具体来说,React应用程序中的数据分为两种类型:
- Props:由父组件传递给子组件的只读属性,不能在子组件中修改;
- 由于Props属性是只读的,因此子组件不能直接修改它们的值。如果需要更新Props属性的值,那么必须由父组件进行更新并重新传递给子组件。
- State:组件内部维护的可变状态,可以通过
setState()
方法进行修改。 - State状态是可变的,可以在组件内部通过
setState()
方法进行修改。当状态发生变化时,React会自动重新渲染并将新的状态值传递给子组件,从而更新子组件的界面
总之,react的数据只能由父组件流向子组件,要改变父组件也只能由组件自身发起
组件间共享数据
这段代码中两个按钮的计数器都是独立更新的,现在我想让两个按钮使用同一个计数:

也就是要将
count
变量的状态移动到MyButton
组件的上一级:MyApp
,然后使用大括号的写法将MyApp
中的count
的状态传给每个子组件:使用这种方式传递的信息被称作 prop
修改子组件以获取从父组件传过来的count和onClick:
当你点击按钮时,
onClick
处理程序会启动。每个按钮的 onClick
prop 会被设置为 MyApp
内的 handleClick
函数,所以函数内的代码会被执行。该代码会调用 setCount(count + 1)
,使得 state 变量 count
递增。新的 count
值会被作为 prop 传递给每个按钮,因此它们每次展示的都是最新的值。这被称为“状态提升”。通过向上移动 state,我们实现了在组件间共享它。父传子
使用类的方式来创建组件:
- 子组件:
- 在组件的constructor里面用props接收父组件传来的数据
- 用state来定义组件内部维护的可变状态(将这个组件所有要用的变量都装在这个里面),代码中用
this.setState({ count: this.state.count + 1 })
来修改count的值而other
保持不变: this.setState({ count: this.state.count + 1 })
只更新了count
,other
的值 不会丢失,仍然是'test'
。- React 会对
this.state
进行浅合并(shallow merge),而不是直接替换整个 state。
可以写接口来规定props和state需具备的属性:
- 父组件:
在
Counter
组件中声明了一个Props属性initialCount
,并在构造函数中使用props
参数来初始化状态变量。这样,当App
组件传递initialCount
属性时,Counter
组件就能够正确地使用该属性使用函数的方式创建组件:也是一样的
子传父
用回调函数:
- 父组件:写一个回调函数传给子组件,这个函数可以修改父组件里面的
state
:
- 子组件:调用父组件传来的回调函数,以此来给父组件传值
父组件调用子组件的方法
子组价将方法绑定到ref上,父组件获取子组件的ref来调用里面的方法
- 子组件:
- 使用
React.forwardRef
包装子组件 - 将子组件的方法绑定到
ref
- 父组件:将ref(useRef返回的)传递给子组件
使用Hook
- 以
use
开头的函数被称为 Hook,useState是内置的一个hook,也可以自己编写hook
- React Hooks 的意思是,组件尽量写成纯函数,如果需要外部功能和副作用,就用钩子把外部代码"钩"进来。 React Hooks 就是那些钩子
- 逻辑复用+响应式:组件复用的话样式也要复用,函数复用的话没有响应式
useState()
useState是一个React Hook函数,它允许我们向组件添加一个状态变量,从而影响组件的渲染结果
类似于toRef

计数器:
官网例子:实现两个独立的点击+次数的按钮
修改状态的规则:
- 在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新
- 相当于用setCount,传入一个新值,这个方法在内部可以实现视图更新
修改对象状态:
- 规则:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
在 React 中,直接修改状态对象不是推荐的做法。比如这段写法就不好:
正确做法是创建一个新对象,并用
setForm()
替换掉原来的:这样 React 才能检测到状态变化,触发组件重新渲染。
当你点击按钮时,它会:
- 调用
setForm
更新form
的值;
- 使用展开运算符
...form
复制form
原有的属性;
- 然后用
name: 'lucy'
覆盖form
中的name
字段。
setXXX里面传一个函数比较好:
- 直接设置可能有问题:
useContext()
如果需要在组件之间共享状态,可以使用
useContext()
- 使用
createContext
在组件外部建立一个Context
:
- 将需要共享上下文的组件封装在里面:
- 子组件通过useContext获取上下文中的属性:
useEffect()
useEffect()
接受两个参数。第一个参数是一个函数,异步操作的代码放在里面。第二个参数是一个数组,用于给出 Effect 的依赖项,只要这个数组发生变化,useEffect()
就会执行。第二个参数可以省略,这时每次组件渲染时,就会执行useEffect()
返回值:
useRef()
用于创建一个可变的引用对象,读写都通过
.current
来访问:- 访问dom元素
- 存储可变值并且不会触发重新渲染:这跟vue的ref不一样,这样声明的变量不是响应式的
- 保存前一个值
useCallback
允许你在多次渲染中缓存函数的 React Hook
The
useCallback
Hook only runs when one of its dependencies update. 但是useCallBack的本质工作不是在依赖不变的情况下阻止函数创建,而是在依赖不变的情况下不返回新的函数地址而返回旧的函数地址。不论是否使用useCallBack
都无法阻止组件render
时函数的重新创建使用场景:
- 使用
React.memo
的时候:
创建自己的hook
封装上面的代码:
然后在一个组件里面调用这个钩子:
组件基础样式方案
index.css:
- import导入,就可以使用里面的样式
- 用className来绑定类名
- 也可以直接写:
常用写法
受控表单绑定
- state绑定到input的value属性
- 把input最新的value值设置到state
- 准备一个react状态值
- 通过value属性绑定状态,通过onChange属性绑定状态同步的函数
input属性变化之后onChange里面的函数就会执行
长列表
FlatList:
FlatList
组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同
FlatList
更适于长列表数据,且元素个数可以增删。和ScrollView
不同的是,FlatList
并不立即渲染所有元素,而是优先渲染屏幕上可见的元素
SectionList:
- 用于渲染一组需要分组和标签的数据
- sections:数据源,必须是一个数组
- renderItem:定义如何渲染每个数据项
- renderSectionHeader:定义如何渲染每个section的header
- keyExtractor:定义列表使用的key
- 每个 section 被单独渲染,包括 header 和它的 data
RN生命周期
生命周期中的钩子函数(方法、事件):
CompontWillMount
:组件将要渲染CompontDidMount
:组件渲染完毕CompontWillReceiveProps
:组件将要接收props数据ShouldComponentUpdate
:组件接收到新的state或者props,判断是否更新,返回布尔值CompontWillUpdate
:组件将要更新ComponentDidUpdate
:组件已经更新ComponentwillUnmount
:组件将要卸载主要的生命周期:
- constructor:
- 组件被实例化的时候触发, 一般用做对组件做初始工作,如设置state等
- render
- 组件开始渲染时触发
- 组件被更新时触发 (state和props发生改变时触发)
- componentDidMount
- 组件挂载完毕,可以发送异步请求获取数据
- componentWillUnmount
- 组件被卸载时触发
- 一般用在清除定时器或者取消订阅等
其他
Native Bridge 原生桥接
原生桥接是 React Native 中 JavaScript 代码和原生代码(iOS/Android)之间通信的机制
工厂函数确保每次都能创建新的组件实例,原生桥接负责 JavaScript 和原生代码之间的通信,原生端管理应用的生命周期和系统级功能
库
lodash
排序:
- orderby(对象数组, ‘按某字段排序’, ‘排序方式(esc/desc)’)
- 返回一个新的数组,不会修改原数组
classnames
可以非常方便地通过条件动态控制class类名的显示

可以用key: value的形式:
- key表示要显示的类名
- value表示控制类名显示的条件
Vue的动态绑定类名和样式:
script:用来控制是否加上active这个类名
redux状态管理
- State 是整个应用在某一时刻的数据快照(由 Redux Store 管理)
- 视图(React)展示 State
- 用户操作或某些事件触发 dispatch(action)
- Redux 的 reducer 根据 action 和旧的 state 生成新的 state
- Redux Store 通知 UI 状态变化
- 视图基于新 state 重新渲染
使用步骤:
- 创建 store,即全局状态容器,里面管理着全局 state
Redux Store = 管理全局状态 + 处理
dispatch
+ 触发 subscribe()
监听更新- provider提供全局状态
这个
ReduxProvider
(来自 react-redux
)把 store 放到 React 的上下文中,这样组件就可以通过 connect()
或 useSelector()
访问到全局状态了- 组件订阅 state + 发出 action
state.counter.num
映射到组件的props.value
dispatch(INCREMENT)
映射到组件的props.onIncrement
(点按钮就能 dispatch)
这个组件通过
connect()
绑定:当组件触发
onIncrement()
,就向 Redux 发出:- Author:orangec
- URL:orange’s blog | welcome to my blog (clovy.top)/article/199c107a-b41d-805f-a76f-d89ebe61ddab
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!