react扩展

1. setState

setState 更新状态的2种写法

  • setstate(statechange[, callback])--对象式的 setState
    1.statechange 为状态改变对象(该对象可以体现出状态的更改)
    2.callback 是可选的回调函数,它在状态更新完毕、界面也更新(render 调用后)才被调用
  • setstate(updater[, callback])--函数式的 setState
    1.updater 为返回 stateChange 对象的函数。
    2.updater 可以接收到 state 和 props。
    3.callback是可选的回调函数,它在状态更新、界面也更新后(render调用后)才被调用。
    总结:
    1.对象式的setState是函数式的setState的简写方式(语法糖)
    2.使用原则:
    (1).如果新状态不依赖于原状态 -> 使用对象方式
    (2).如果新状态依赖于原状态 -> 使用函数方式
    (3).如果需要在setState() 执行后获取最新的状态数据,要在第二个callback函数中读取

2. lazyLoad

路由组件的lazyLoad

//1.通过React的lazy函数配合import()函数动态加载路由组件,路由组件代码会被分开打包
const Login = lazy(() => import('@/pages/Login'))

//2.通过<Suspense>指定在加载得到路由打包文件前显示一个自定义1oading界面 
<Suspense fallback={<h1>1oading. .</h1>]}>
  <Switch>
    <Route path="/xxx" component={Xxxx}/>
    <Redirect to="/login"/>
  </Switch>
</Suspense>

3. Hooks

1. React Hook/Hooks 是什么?

  • Hook 是 React16.8.0 版本增加的新特性/新语法
  • 可以让你在函数组件中使用 state 以及其他的 React 特性

2.三个常用的 Hook

  • State Hook: React.useState()
  • Effect Hook: React.useEffect()
  • Ref Hook: React.useRef()

3.State Hook

  • State Hook 让函数组件也可以有 state 状态,并进行状态数据的读写操作
  • 语法:const [xxx,setxxx] = React.usestate(initvalue)
  • useState() 说明:
    参数:第一次初始化指定的值在内部作缓存
    返回值:包含2个元素的数组,第1个为内部当前状态值,第2个为更新状态值的函数
  • setXxx() 两种写法:
    setXxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
    setxxx(value =>newValue):参数为函数,接收原本的状态值,返回新的状态值,内部用其覆盖原来的状态值

4.Effect Hook

  • Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
  • React中的副作用操作:
    发 ajax 请求数据获取
    设置订阅/启动定时器
    手动更改真实 DOM
  • 语法和说明:
    useEffect(()=>{
      //在此可以执行任何带副作用操作
      return()=>{//在组件卸载前执行
      //在此做一些收尾工作,比如清除定时器/取消订阅等
      }
    }[stateValue])//如果指定的是[],回调函数只会在第一次render()后执行
    
  • 可以把 useEffect Hook 看做如下三个函数的组合
    componentDidMount()
    componentDidUpdate()
    componentWillUnmount()
    

5. useLayoutEffect()

useLayoutEffect 是 useEffect 的一个版本,在浏览器重新绘制屏幕之前触发。

6. Ref Hook

  • Ref Hook 可以在函数组件中存储/查找组件内的标签或任意其它数据
  • 语法:const refcontainer = useRef()
  • 作用:保存标签对象,功能与 React.createRef() 一样

7. useMemo()

useMemo 它使用来做缓存用的,只有当一个依赖项改变的时候才会发生变化,否则拿缓存的值,就不用在每次渲染的时候再做计算

import { useMemo } from 'react';

const getNumMemo = useMemo(() => {
  return count * 10
}, [count])

8. memo()

在 react 的一般规则中,只有父组件的某一个状态改变,父组件下面所有的子组件不论是否使用了该状态,都会进行重新渲染。显然,对于没有用到被改变的那个状态的组件来说,重新渲染是完全没有必要的。所以,React.memo 就诞生了。

import { memo } from 'react';

const Child = () => {}
export default memo(Child)

9. useCallback()

  • useCallBack 的本质工作不是在依赖不变的情况下阻止函数创建,而是在依赖不变的情况下不返回新的函数地址而返回旧的函数地址。不论是否使用 useCallBack 都无法阻止组件 render 时函数的重新创建!!
  • 在往子组件传入了一个函数并且子组件被 React.memo 缓存了的时候使用
import { useCallback } from 'react';

const updateCount = useCallback(() => console.log('父业务'), [])
return(
  <Child updateCount={updateCount}></Child>
)

4. Fragment 使用

//作用:可以不用必须有一个真实的DOM根标签了
<Fragment key="xxx"><Fragment> 
<></>

5.Context

理解

一种组件间通信方式,常用于【祖组件】与【后代组件】间通信

使用

  • 创建 Context 容器对象:
    const XxxContext = React.createContext()
  • 渲染子组件时,外面包裹 xxxContext.Provider,通过 value 属性给后代组件传递数据:
    <XxxContext.Provider value={数据}>
      子组件
    </XxxContext.Provider>
    
  • 后代组件读取数据:
    //第一种方式:仅适用于类组件
    static contextType = XxxContext //声明接收context 
    this.context //读取context中的value数据
    //第二种方式:函数组件与类组件都可以
    <XxxContext.Consumer>
      {
        value => (//value就是context中的value数据
          要显示的内容
        )
      }
    </XxxContext.Consumers>
    //第三种方式:函数组件
    import { useContext } from 'react'
    const { count } = useContext(AppContext)
    

注意

在应用开发中一般不用 context,一般都用它的封装 react 插件

6.组件优化

Component 的2个问题

1.只要执行 setState(),即使不改变状态数据,组件也会重新 render()
2.只当前组件重新 render(),就会自动重新 render 子组件,即使子组件没有用到父组件的任何数据 效率低

效率高的做法

只有当组件的 state 或 props 数据发生改变时才重新 render()

原因

Component 中的 shouldComponentUpdate() 总是返回 true

解决

办法1:
  重写 shouldcomponentUpdate(nextProps, nextState) 方法
  比较新旧 state 或 props 数据,如果有变化才返回 true,如果没有返回 false
办法2:
  使用 PureComponent
  PureComponent 重写了 shouldcomponentUpdate(),只有 state 或 props 数据有变化才返回 true 
  注意:
    只是进行 state 和 props 数据的浅比较,如果只是数据对象内部数数据变了,返回 false
    不要直接修改 state 数据,而是要产生新数据
  项目中一般使用 PureComponent 来优化

7.render props

如何向组件内部动态传入带内容的结构(标签)?

Vue 中:
  使用 slot 技术,也就是通过组件标签体传入结构 <A><B/></A> 
React中:
  使用 children props:通过组件标签体传入结构
  使用 render props:通过组件标签属性传入结构,而且可以携带数据,一般用 render 函数属性

children props

//父组件
<A>
  <B>xxxx</B>
</A>
//子组件
{this.props.children}
问题:如果B组件需要A组件内的数据,做不到

render props

<A render={(data) => <B data={data}></B>}></A> 

A组件:{this.props.render(内部state数据)}
B组件:读取A组件传入的数据显示{this.props.data}

8.错误边界

理解:

错误边界(Error bolundary):用来捕获后代组件错误,渲染出备用页面

特点:

只能捕获后代组件 生命周期 产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误

使用方式:

getDerivedStateFromError 配合 componentDidCatch

//生命周期函数,一旦后台组件报错,就会触发
static getDerivedstateFromError (error){ 
  console.1og(error);
  //在render之前触发
   //返回新的state
  return {
   hasError: error,
  };
}
componentDidcatch(error, info){
  //统计页面的错误。发送请求发送到后台去
  console.log(error, info);
}

9.组件通信方式总结

组件间的关系:

父子组件
兄弟组件(非嵌套组件)
祖孙组件(跨级组件)

几种通信方式:

1.props:
  (1).children props 
  (2).render props 
2.消息订阅-发布:
  pubs-sub、event等等
3.集中式管理:
  redux、dva等等
4.Context:
  生产者-消费者模式

比较好的搭配方式:

父子组件:props
兄弟组件:消息订阅-发布、集中式管理
祖孙组件(跨级组件):消息订阅-发布、集中式管理、conText(开发用的少,封装插件用的多)
posted @   提莫一米五呀  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示