2018-09-19盤点React 16.0~16.5主な更新とその応用(転載)を発表します.

32787 ワード

約一年前、ReactチームはReact 16.0を発表しました.今では16.5に更新されました.この中には多くの人の心を奮い立たせる特性(例えば、Fiberアーキテクチャの導入、新しい周期関数、新しいContect API、Fragment、Err Boundary、Portalなど)があります.この文章は  React更新ログ そのために、いくつかの重要かつ仕事の更新のために、みんなと一緒に勉強します.すべてのコード例は  react-ugrade-examplesは、文章と一緒に食べたほうがいいです.
目次
0.ライフサイクル関数の更新
1.全く新しいContect API
2.React Strict Mode
3.Portal
4.Refs
5.Fragment
6.その他
7.まとめ
ライフサイクル関数の更新
React 16.0の発表に伴い、Reactは新たなカーネルアーキテクチャFiberを採用し、新たなアーキテクチャでは、Render ParsとComit Parseに分けて更新され、これによって導入された.  getDerivedStateFromProps 、  getSnapshotBeforeUpdate および  componentDidCatch などの3つのライフサイクル関数.と同時に  componentWillMountcomponentWillReceiveProps 和  componentWillUpdate 安全でない方法としてマークします.
new lifecycle
追加
  • static getDerivedStateFromProps(nextProps, prevState)
  • getSnapshotBeforeUpdate(prevProps, prevState)
  • componentDidCatch(error, info)
  • 危険としてマーク
  • componentWillMount(nextProps, nextState)
  • componentWillReceiveProps(nextProps)
  • componentWillUpdate(nextProps, nextState)
  • static getDerivedStateFromProps(nextProps, prevState)によると  getDerivedStateFromProps(nextProps, prevState) の関数署名が分かります.その役割は伝達によるものです.  props 更新します  state.その大きな特徴の一つは 副作用がない : Render Phaseの段階にあるので、更新のたびにトリガされるので、APIを設計する時に静的な方法を採用しています.その利点は単純です.  ref DOMオブジェクトにアクセスするなど、単純かつ効率的にアクセスすることができます.注意に値するのは、まだ通ることができることです.  props の操作で副作用が発生します.  props の方法を移動します  componentDidUpdate でトリガ回数を減らす.
    例:
     1 state = { isLogin: false }
     2 
     3 static getDerivedStateFromProps(nextProps, prevState) {
     4   if(nextProps.isLogin !== prevState.isLogin){
     5     return {
     6       isLogin: nextProps.isLogin
     7     }
     8   }
     9   return null
    10 }
    11 
    12 componentDidUpdate(prevProps, prevState){
    13   if(!prevState.isLogin && prevProps.isLogin) this.handleClose()
    14 }
     
    でも、使う時は、似ていないので、注意してください.  componentWillReceiveProps 同じように、親コンポーネントの再レンダリング時のみトリガし、自分で起動します.  setState トリガーにもなります.公式は3つのチェックリストを提供しています.ここで運んでください.
  • 変更したら  props と同时に、副作用が発生します.  componentDidUpdate
  • 根拠がほしいなら  props 属性を計算します.結果をmemoization化することを考慮して、参照してください. memoization
  • 根拠がほしいなら  props いくつかの状態をリセットするために、制御されたコンポーネント
  • を使用することを考慮すべきである.
    配合  componentDidUpdate サイクル関数 代わりに  getDerivedStateFromProps 現れたのは.元にします  componentWillReceiveProps 機能の区分——更新  componentWillReceiveProps および操作/呼び出し  stateは、職責の不備による過剰なレンダリングを大きく避け、性能に影響を与える.propsによると  getSnapshotBeforeUpdate(prevProps, prevState) の関数署名により、コンポーネントが更新される前にsnapshotを取得することができます.計算された値またはDOMから得られた情報を送ることができます.  getSnapshotBeforeUpdate(prevProps, prevState) 周期関数の3番目のパラメータは,しばしばscroll位置の局在化に用いられる.公式の例から.
     1 class ScrollingList extends React.Component {
     2   constructor(props) {
     3     super(props)
     4     //   dom   
     5     this.listRef = React.createRef()
     6   }
     7 
     8   getSnapshotBeforeUpdate(prevProps, prevState) {
     9     //                      
    10     if (prevProps.list.length < this.props.list.length) {
    11       const list = this.listRef.current
    12       return list.scrollHeight - list.scrollTop
    13     }
    14     return null
    15   }
    16 
    17   componentDidUpdate(prevProps, prevState, snapshot) {
    18     //    snapshot        ,        
    19     if (snapshot !== null) {
    20       const list = this.listRef.current
    21       list.scrollTop = list.scrollHeight - snapshot
    22     }
    23   }
    24 
    25   render() {
    26     return 
    this.listRef}>{ /* ...contents... */}
    27 } 28 }
      componentDidUpdate(prevProps, prevState, snapshot)16.0以前に、エラーキャプチャ使用  componentDidCatch(error, info) または第三者ライブラリを採用する場合 react-error-overlay これにより捕獲された前者の情報は非常に限定されており、後者は非公式の支持である.16.0で増加しました.  unstable_handleError 周期関数によって、開発者は、ディスプレイ、レポートエラーなどのエラー情報を自主的に処理することができ、ユーザは自分のcomponentDidCatchを作成することができる. を選択します.例:
     1 ···
     2 
     3  componentDidCatch(error, info) {
     4     // Display fallback UI
     5     this.setState({ hasError: true });
     6     // You can also log the error to an error reporting service
     7     logErrorToMyService(error, info);
     8   }
     9 
    10 ···
     
    また、ユーザは、第三者のエラー追跡サービスを採用することもできます. センタリー、Bugsnag など、エラー処理効率を保証するとともに、中小型プロジェクトのエラー追跡のコストを大幅に低減しました.
    写真bugsnag
    危険としてマーク  Error BoundarycomponentWillMountcomponentWillReceivePropscomponentWillUpdatecomponentWillMountcomponentWillMount 開発者は、最初のスクリーンデータまたはトランザクション購読を取得するために使用できます.
    開発者は素早くデータを得るために、最初のスクリーンに要求を置いています.  componentWillMountにあります.実際に実行しています  componentWillMountの時、初めてレンダリングが開始されました.最初のスクリーンリクエストをcomponentWillMountに置いてください. の有無はすべて解決できません.公式の提案は、最初のスクリーンを置くことです.  constructor または  componentDidMountにあります
    またイベント購読も頻繁に行われています.  componentWillMount 使用します  componentWillUnmount をクリックします.でも、Reactは保証できません.  componentWillMount 呼び出し後、同じコンポーネントの  componentWillUnmount 必ず呼び出されます.一方、将来的にはReactが非同期レンダリングモードをオンした後、・呼び出し後、コンポーネントのレンダリングが他の事務所に中断される可能性が高い.  componentWillUnmount コールされません.に対する  componentDidMount この問題は存在しません.  componentDidMount 呼び出し後、componentWillUnmount 必ず後で呼び出されます.具体的なコードに従って、コンポーネントに存在するイベントをクリアして購読します.
    このアップグレードプランは  componentWillMount に変更する  componentDidMount いいですcomponentWillReceivePropscomponentWillUpdatecomponentWillReceiveProps 安全でないとラベル付けされた理由は、前述の通り、その主な原因は操作propsによるre-renderである.これに類する  componentWillUpdate 安全でないと表記されているのも同じ理由です.これ以外にも、DOMの更新動作が再レンダリングを引き起こす可能性がある.
    に対する  componentWillReceiveProps のアップグレードプログラムは使用です.  getDerivedStateFromProps 和  componentDidUpdate 代わりに.に対する  componentWillUpdate のアップグレードプログラムは使用です.  componentDidUpdate 代わりに.大量の計算にかかわったら  getSnapshotBeforeUpdate 計算をしてから、また  componentDidUpdate 一回で更新が完了します.
    フレームレベルのAPIによって、開発者がよりメンテナンスしやすいJavascriptコードを作成することを制限したり、制限したりして、反モードの開発方式を最大限に避けました.
    新しいContect API
    React 16.3の前にContect APIはずっと公式に置かれていますが、その原因は古いContect APIが一つの実験的な製品として、Reactのフラクタル構造を破壊したからです.同時に使用する過程で、コンポーネントを突き抜ける過程で、あるコンポーネントの  shouldComponentUpdate 戻りました  falseでは、Context APIは貫通できなくなります.その不確実性は、不推奨の使用につながります.React 16.3の発表に伴って、新しいContect APIは一等APIとなり、コンポーネントを通して副作用がなくても容易に利用できます.公式の例示コード:
     1 // Context lets us pass a value deep into the component tree
     2 // without explicitly threading it through every component.
     3 // Create a context for the current theme (with "light" as the default).
     4 const ThemeContext = React.createContext('light')
     5 
     6 class App extends React.Component {
     7   render() {
     8     // Use a Provider to pass the current theme to the tree below.
     9     // Any component can read it, no matter how deep it is.
    10     // In this example, we're passing "dark" as the current value.
    11     return (
    12       
    13         
    14       
    15     )
    16   }
    17 }
    18 
    19 // A component in the middle doesn't have to
    20 // pass the theme down explicitly anymore.
    21 function Toolbar(props) {
    22   return (
    23     
    24 25
    26 ) 27 } 28 29 function ThemedButton(props) { 30 // Use a Consumer to read the current theme context. 31 // React will find the closest theme Provider above and use its value. 32 // In this example, the current theme is "dark". 33 return ( 34 {theme =>

    全新的 Context API 带来的穿透组件的能力对于需要全局状态共享的场景十分有用,无需进入额外的依赖就能对状态进行管理,代码简洁明了。

    React Strict Mode

    React StrictMode 可以在开发阶段发现应用存在的潜在问题,提醒开发者解决相关问题,提供应用的健壮性。其主要能检测到 4 个问题:

    • 识别被标志位不安全的生命周期函数
    • 对弃用的 API 进行警告
    • 探测某些产生副作用的方法
    • 检测是否采用了老的 Context API

    使用起来也很简单,只要在需要被检测的组件上包裹一层 React StrictMode ,示例代码 React-StictMode:

     1 class App extends React.Component {
     2   render() {
     3     return (
     4       
    5 6 7 8
    9 ) 10 } 11 }
    エラーが発生したら、コンソールで具体的なエラー情報を出力します.
    React Strict Mode
     
    Portal
    ReactDOMから提供された  createPortal 方法は、コンポーネントを他のDOMノードにレンダリングすることができます.これは、大きなアプリケーションまたはアプリケーション自体とは独立したレンダリングに役立ちます.関数署名はReactDOM.createPortal(child, container)です.  child パラメータは任意のレンダリング可能なReact Componentです.  elementstingfragmentcontainer 等、props マウントするDOMノードです.
    簡単なModalを例にして、コードを参照してください. Portal Modal :
     1 import React from 'react'
     2 import ReactDOM from 'react-dom'
     3 const modalRoot = document.querySelector('#modal')
     4 
     5 export default class Modal extends React.Component {
     6   constructor(props) {
     7     super(props)
     8     this.el = document.createElement('div')
     9   }
    10   componentDidMount() {
    11     modalRoot.appendChild(this.el)
    12   }
    13   componentWillUnmount() {
    14     modalRoot.removeChild(this.el)
    15   }
    16   handleClose = () => [this.props.onClose && this.props.onClose()]
    17   render() {
    18     const { visible } = this.props
    19     if (!visible) return null
    20 
    21     return ReactDOM.createPortal(
    22       
    23 { this.props.children} 24 this.handleClose}>[x] 25
    , 26 this.el 27 ) 28 } 29 }
     
    具体的な過程は使うことです.  children 転送  ReactDOM.createPortalの後、使用する.  refは、containerを他のDOMノードにレンダリングするプロセスである.
    Refs
    ReactはVirtual DOMを使ってビューを更新しますが、ある時は本当のDOMを操作します.  React.createRef 属性が役に立ちます.React.createRefReact 16は使用しました   Refオブジェクトを取得するには、これまでの方法とはかなり違っています.
     1 // before React 16
     2 ···
     3 
     4   componentDidMount() {
     5     // the refs object container the myRef
     6     const el = this.refs.myRef
     7     // you can  also using ReactDOM.findDOMNode
     8     // const el = ReactDOM.findDOMNode(this.refs.myRef)
     9   }
    10 
    11   render() {
    12     return 
    13 } 14 ··· 15 ··· 16 // React 16+ 17 constructor(props) { 18 super(props) 19 this.myRef = React.createRef() 20 } 21 22 render() { 23 return
    this.myRef} /> 24 } 25 ··· 26 React.forwardRef 27 Ref , Ref, DOM。 28 React.forwardRef , props ref。 , Refs: 29 30 const TextInput = React.forwardRef((props, ref) => ( 31 32 )) 33 const inputRef = React.createRef() 34 35 class App extends Component { 36 constructor(props) { 37 super(props) 38 this.myRef = React.createRef() 39 } 40 41 handleSubmit = event => { 42 event.preventDefault() 43 alert('input value is:' + inputRef.current.value) 44 } 45 render() { 46 return ( 47
    this.handleSubmit}> 48 49 50 51 ) 52 } 53 }

     

     React.forwardRef   props   ref  , 。

    Fragment

    DOM , document.createDocumentFragment,  DocumentFragment  ,  DocumentFragment  DOM , DOM 。

     DocumentFragment  ,React  Fragment  , 。 React 16 ,Fragment  react-addons-create-fragment  , React 16    'Fragment'。 :

    1 render() {
    2   return (
    3     
    4       
    5       
    6       
    7     
    8   )
    9 }
     
    このように、 は で な の を む はないです. の  ), 。
    , :

    1 render() {
    2   return (
    3     <>
    4       
    5       
    6       
    7     >
    8   )
    9 }

     

    ReactDOM  は でReact Componentに ります.
    1 render(){
    2   return [
    3     ,
    4     ,
    5   ]
    6 }
     
    に されたrenderを し、すべてのプラグインが して てきます.
    よく われていたreact-with-addons.jsreact-addons-(css-)transition-groupreact-addons-create-fragmentreact-addons-pure-render-mixin など、 が されている はすべて して つの として いますので、 してください.
    め りをつける
    を て、React 16.0~16.5のアップグレードは により な プロセスを えました.APIレベルの 、アーキテクチャの 、ツール の はよりメンテナンスしやすいJavaScriptアプリケーションを するために しています. を し、 に します.
    の には りがありますので、 の には があります.
    です
    Find me on Github
    :
  • React Docs
  • Update on Async Rendering
  • You Probably Don't Need Derived State
  • React v 16.3バージョンの ライフサイクル およびアップグレードプログラム
  • React 16:A look inside an API-comptible rewrite of our frontend UI library
  • React Fiber Architecture
  • :https://www.cnblogs.com/fpj-frank/p/9969439.html