与类组件是等效的。类组件是有
render
方法的,state数据改变就会重新渲染UI。
function User(props) {return <h1>Hello, {props.name}</h1>}
函数组件是怎么做到数据变化重新渲染UI的?函数组件属于无状态组件
事件处理函数
不想通过
bind
绑定
this
,可以在
constructor
中绑定方法、使用箭头函数、继续使用
createReactClass
。
回调箭头函数作为
prop
传入子组件时,这些组件可能会进行额外的重新渲染。建议在构造器中绑定或使用
class fields
语法来避免这类性能问题。
向事件处理程序传递参数
使用箭头函数事件
e
需显式传
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
列表
key
值
在列表项目顺序发生变化的情况下不建议使用索引,可能会引起组件状态的问题(原因??)。
key
会传递给
React
而不会传递给你的组件
深入解析为什么 key 是必须的
深度解析使用索引作为 key 的负面影响
React.lazy
接受一个函数,这个函数必须动态调用
import
。能缩减
bundle.js
的体积,并延时加载在初次渲染时未用到的组件
lazy
组件应在
Suspense
组件中渲染,在等待
lazy
组件渲染时做优雅降级。
Suspense
组件的
fallback
属性能接受任何在组件加载过程中你想展示的元素。
异常捕获边界
在模块加载失败时,用异常捕获边界来处理,能有更好的用户体验
context
React.createContext()
使用
context
可以避免中间元素传递
props
context
主要用于很多不同层级的组件需要访问同样的数据。需谨慎使用,会使组件的复用性变差
React.Fragment
包裹一组子节点,但不返回本身的节点。减少不必要嵌套的组件。简写
<> </>
,简写形式不支持
key
或属性。
在写组件时,习惯用
div
将作为最外层将所有的节点包起来,但这样会渲染出一些没必要的节点
该属性可以作为组件的标识,值可以通过
React.createRef()
创建,也可以是回调函数,回调函数它的参数是当前的
DOM
元素,这个回调函数一般干的事情就是存储指向该
DOM
元素的引用。回调函数会在组件挂载/卸载/
ref
属性本身发生变化时调用。
也可以在实例组件中使用
ref
,但实例组件的类型只能是
class
组件。
refs
转发
可以将子组件的
DOM
节点暴露给父组件。子组件需要用
React.forwardRef()
来获取传递给它的
ref
,然后转发到它渲染的
DOM
节点上
可以获取到
DOM
节点。直接传递值为
React.createRef()
的ref只能取到实例组件
高阶函数
HOC
是参数为组件,返回值为新组件的函数,不会改变传入的参数。被包装的组件最好透传
props
HOC
是纯函数,没有副作用。可以参考React官方给出的例子:
高阶函数
;不要在
render
组件中使用
HOC
,会有性能问题,也会导致该组件及其所有子组件的状态丢失。这与
React diff
算法有关
1.生产环境使用React 2.明确什么时候需要更新组件时,使用
shouldComponentUpdate
3.使用
React.PureComponent
进行浅比较
React.PureComponent
中以浅层对比
prop
和
state
的方式来实现了
shouldComponentUpdate
需要
value
属性和
onChange
回调函数,需要通过
state
来维护用户的输入
在表单有默认值或需要编辑的时候使用。
非受控组件
就像传统的
HTML form
,用
ref
来获取用户的输入
只需要用户输入,比如创建表单时使用。
ReactDOMServer
提供了两个在node端和浏览器端均可使用的方法:
renderToString
、
renderToStaticMarkUp
;两个只能在
node
端使用的方法
renderToNodeStream
、
renderToStaticNodeStream
后两种方法需要依赖只能在服务端使用的
stream package
renderToString()
可以使用此方法在服务端生成
HTML
,并在首次请求时将标记下发,以加快页面加载速度,并允许搜索引擎爬取你的页面以达到
SEO
优化的目的。
renderToStaticMarkup
与
renderToString
相似,但前者不会在
React
内部创建的额外
DOM
属性,例如
data-reactroot
。如果你希望把
React
当作静态页面生成器来使用,此方法会非常有用,因为去除额外的属性可以节省一些字节。
dangerouslySetInnerHTML
是
React
为浏览器
DOM
提供
innerHTML
的替换方案
在不用编写
class
组件的情况下使用
state
和
React
的一些其他特性
只能在
函数组件中使用
。常用的
Hooks
有
useState
、
UseEffect
// 函数组件使用自定义``Hook``
function FriendStatus(props) {
const isOnline = useFriendStatus(props.friend.id);
if (isOnline === null) {
return 'Loading...';
return isOnline ? 'Online' : 'Offline';
2.
使用
Hook
实现倒计时
function CountDown() {
const [count, setCount] = useState(100);
useEffect(() => {
let timer;
if(count > 0) {
timer = setInterval(() => {
setCount(count - 1)
}, 1000);
return () => {
clearInterval(timer);
}, [count])
return (<div>
{count}
</div>)
3.用useState
初始化一个数据结构复杂的state
,在更新该数据中某个属性时,需要整体更新吗?当state
是对象时从,采用合并更新来更新state
对象,以防旧的属性丢失:
function UpdateState() {
const [ info, setInfo ] = useState({ name: '', age: 0 });
updateInfo(e) {
setInfo({
...info,
[e.target.name]: e.target.value,
4.生命周期方法如何对应到Hook
先回顾下最新的生命周期函数