React16新增特性

2020-03-01  本文已影响0人  葶寳寳
新增特性/需要关注的点 说明 使用场景 or 备注
函数组件 与类组件是等效的。类组件是有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将作为最外层将所有的节点包起来,但这样会渲染出一些没必要的节点
ref 该属性可以作为组件的标识,值可以通过 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 中以浅层对比 propstate 的方式来实现了shouldComponentUpdate
受控组件 需要value属性和onChange回调函数,需要通过state来维护用户的输入 在表单有默认值或需要编辑的时候使用。
非受控组件 就像传统的HTML form,用ref来获取用户的输入 只需要用户输入,比如创建表单时使用。
ReactDOMServer 提供了两个在node端和浏览器端均可使用的方法:renderToStringrenderToStaticMarkUp;两个只能在node端使用的方法renderToNodeStreamrenderToStaticNodeStream 后两种方法需要依赖只能在服务端使用的stream package
renderToString() 可以使用此方法在服务端生成 HTML,并在首次请求时将标记下发,以加快页面加载速度,并允许搜索引擎爬取你的页面以达到 SEO优化的目的。 renderToStaticMarkuprenderToString相似,但前者不会在 React 内部创建的额外DOM 属性,例如 data-reactroot。如果你希望把 React 当作静态页面生成器来使用,此方法会非常有用,因为去除额外的属性可以节省一些字节。
dangerouslySetInnerHTML React 为浏览器 DOM 提供 innerHTML 的替换方案
Hook 在不用编写class组件的情况下使用stateReact的一些其他特性 只能在函数组件中使用。常用的HooksuseStateUseEffect

如何实现一个纯函数??

1.通过自定义Hook实现组件之间重用状态逻辑。自定义Hook更像是一种约定而不是功能。

还可以通过高阶组件和render props来实现组件之间重用状态逻辑

// 自定义Hook
import React, { useState, useEffect } from 'react';

function useFriendStatus(id){
    const [isOnline, setIsOnline] = useState(null);

    useEffect(() => {
        function handleStatusChange(status) {
            setIsOnline(status.isOnline);
        } 

        ChatAPI.subscribeToFriendStatus(id, handleStatusChange);

        return () => { 
            ChatAPI.unsubscribeFromFriendStatus(id, handleStatusChange);
        }
    })

    return isOnline;
}

// 函数组件使用自定义``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
先回顾下最新的生命周期函数

image.png
生命周期函数 Hook
constructor 函数组件不需要构造函数。通过useState来初始化state
getDerivedStateFromProps 在渲染时安排一次更新。可以将上一轮的prop存入state以便比较
shouldComponentUpdate React.memo包裹一个组件来对它的props进行浅比较,函数返回true就会跳过更新
render 就是函数组件本身
componentDidMountcomponentDidUpdatecomponentWillMount 利用useEffect Hook可以做到
componentDidCatchcomponentDerviedFormError 暂无这些方法的Hook等价写法
上一篇下一篇

猜你喜欢

热点阅读