ホームページ  >  記事  >  ウェブフロントエンド  >  React 16.3 の新機能の分析

React 16.3 の新機能の分析

小云云
小云云オリジナル
2018-02-09 15:36:454287ブラウズ

Context API は常に混乱を招きます。この API は公式ですが、公式はこの API は将来変更されるとして、開発者にこの API を使用してほしくないと考えています。今こそその変化の時です。新しい API が統合されました。そして、より「ユーザーフレンドリー」に見えます。特に redux または mobx を使用する必要がある場合は、新しい Context API を選択して、よりシンプルな状態管理を実現できます。

新しい API は非常に簡単に使用できます: React.createContext() により、2 つのコンポーネントが作成されます: React.createContext(),这样就创建了两个组件:

import {createContext} from 'react';

const ThemeContext = createContext({
  background: 'yellow',
  color: 'white'
});

调用createContext方法会返回两个对象,一个是Provider,一个是Consumer

那个Provider是一个特殊的组件。它可以用来给子树里的组件提供数据。一个例子:

class Application extends React.Component {
  render() {
    <ThemeContext.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
      <Header />
      <Main />
      <Footer />
    </ThemeContext.Provider>
  }
}

上例展示了如何传递“theme” context的。当然这些值可以是动态的(比如,基于this.state)。

下一步就是使用Consumer

const Header = () => {
  <ThemeContext.Consumer>
    {(context) => {
      return (
        <p style={{background: context.background, color: context.color}}>
          Welcome!
        </p>
      );
    }}
  </ThemeContext.Consumer>
}

如果在render Consumer的时候没有嵌套在一个Provider里面。那么就会使用createContext方法调用的时候设置的默认值。

注意:

  • Consumer必须可以访问到同一个Context组件。如果你要创建一个新的context,用的是同样的入参,那么这个新建的context的数据是不可访问的。因此,可以把Context当做一个组件,它可以创建一次,然后可以export,可以import。

  • 这个新的语法用了function as child模式(有时也叫做render prop模式)。如果不是很熟悉这个模式,那么推荐你看一下这些文章。

  • 新的API不再要求你声明contextProps了。

Context传递的数据和Context.Provider组件的value属性是一样的。对Provider数据的修改会引起所有的消费者(consumer)重绘。

新的声明周期方法

参考这个RFC。新的声明周期方法会被引入,而旧的会被废弃。

这一改变主要是为了强制推行最佳实践。你可以看看这篇文章来了解一下为什么这些生命周期方法会变得很诡异。这些最佳模式在React 16的异步绘制模式(Async Mode)下显得非常重要。

要被废弃的方法:

  • componentWillMount--使用componentDidMount代替

  • componentWillUpdate--使用componentDidUpdate代替

  • componentWillReceiveProps--使用一个新的方法:static getDerivedStateFromProps来代替。

不过这些并不会立刻发生,他们可以用到React 16.4。在React 17里将被彻底移除。如果你开启了StrictMode或者AsyncMode,可以通过这样的方式来使用,但是会收到警告:

  • UNSAFE_componentWillMount

  • UNSAFE_componentWillReceiveProps

  • UNSAFE_componentWillUpdate

static getDerivedStateFromProps

componentWillReceiveProps我们需要其他的方式根据props的变动更新state。社区决定引入一个新的static方法来处理这个问题。

什么是静态方法?一个静态方法就是存在于类内,而不是类的实例内的方法。静态方法访问不到this,并且在声明的时候有static关键字在前面修饰。

但是,问题来了。既然这个方法没有办法访问this,那么如何调用this.setState呢?答案就是,不调用。这个方法直接返回需要更新的state的数据,或者返回null,如果没有什么需要更新的话。

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.currentRow === prevState.lastRow) {
    return null;
  }

  return {
    lastRow: nextProps.currentRow,
    isCrollingDown: nextProps.curentRow > prevState.lastRow
  }
}

调用这个方法和之前调用this.setState的效果是一样的。只会修改这些返回的值,如果是null的话则不修改state。state的其他值都会保留。

值得注意的事

你需要定义初始state的值。无论是在constructor里,或者是类属性。否则会报警告。

这个方法getDerivedStateFromProps()会在第一次挂载和重绘的时候都会调用到,因此你基本不用在constructor里根据传入的props来setState

如果定义了getDerivedStateFromProps后,又定义了componentWillReceiveProps。那么,只有前者会被调用,并且你会收到一个警告。

一般你会使用一个回调来保证某些代码实在state更新之后才被调用的。那么,请把这些代码都移到componentDidUpdate里。

如果你不喜欢使用static

ComponentName.getDerivedStateFromProps = (nextProps, prevState) => {
  // Your code here
}
createContext メソッドを呼び出すと 2 つのオブジェクトが返されます。 プロバイダ、もう 1 つは コンシューマ です。 🎜🎜その プロバイダ は特別なコンポーネントです。これを使用して、サブツリー内のコンポーネントにデータを提供できます。例: 🎜
import {StrictMode} from 'react'

class Application extends React.Component {
  render() {
    return (
      <StrictMode>
        <Context.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}
🎜 上記の例は、「テーマ」コンテキストを渡す方法を示しています。もちろん、これらの値は動的にすることもできます (たとえば、this.state に基づく)。 🎜🎜次のステップは、Consumer を使用することです。 🎜rrreee🎜Consumer をレンダリングするときに Provider にネストされていない場合。その後、createContext メソッドの呼び出し時に設定されたデフォルト値が使用されます。 🎜🎜注意: 🎜
  • 🎜消費者は同じコンテキストにアクセスできる必要があります。コンポーネント。新しいコンテキストを作成して同じ入力パラメーターを使用する場合、この新しいコンテキストのデータにはアクセスできなくなります。したがって、コンテキストはコンポーネントとみなすことができ、一度作成してからエクスポートおよびインポートできます。 🎜
  • 🎜この新しい構文は、関数を子モード (レンダー プロップ モードとも呼ばれる) として使用します。このモデルにあまり詳しくない場合は、これらの記事を読むことをお勧めします。 🎜
  • 🎜 新しい API では、contextProps を宣言する必要がなくなりました。 🎜
🎜Context によって渡されるデータは、Context.Provider コンポーネントの value 属性と同じです。 Provider データを変更すると、すべてのコンシューマが再描画されます。 🎜

新しいライフサイクル方法

🎜この RFC を参照してください。新しいライフサイクルメソッドが導入され、古いライフサイクルメソッドは廃止されます。 🎜🎜この変更は主にベスト プラクティスを強制することを目的としています。この記事を読むと、これらのライフサイクル メソッドが奇妙になる理由を理解できます。これらの最適なモードは、React 16 の非同期描画モード (Async モード) において非常に重要です。 🎜🎜非推奨となるメソッド: 🎜
  • 🎜componentWillMount -- 🎜
  • の代わりに componentDidMount を使用します。
  • 🎜componentWillUpdate -- 🎜
  • の代わりに componentDidUpdate を使用します
  • 🎜componentWillReceiveProps -- 新しいメソッドを使用します: static getDerivedStateFromProps を使用してください。 🎜
🎜 ただし、これはすぐには実現しません。React 16.4 を使用できます。 React 17 では完全に削除される予定です。 StrictMode または AsyncMode を有効にすると、この方法で使用できますが、次の警告が表示されます: 🎜
    🎜UNSAFE_componentWillMount🎜
  • 🎜UNSAFE_componentWillReceiveProps🎜
  • 🎜UNSAFE_componentWillUpdate🎜

static getDerivedStateFromProps

🎜componentWillReceiveProps の場合、props の変更に従って状態を更新する他の方法が必要です。コミュニティは、この問題に対処するために新しい静的方法を導入することを決定しました。 🎜🎜静的メソッドとは何ですか?静的メソッドは、クラスのインスタンス内ではなく、クラス内に存在するメソッドです。静的メソッドは this にアクセスできず、宣言時にメソッドの前に static キーワードを付けて変更されます。 🎜🎜しかし、ここで問題が発生します。このメソッドには this にアクセスする方法がないため、this.setState を呼び出すにはどうすればよいでしょうか?答えは電話しないでくださいです。このメソッドは、更新する必要がある状態データを直接返します。更新するものがない場合は null を返します。 🎜rrreee🎜 このメソッドを呼び出すと、以前に this.setState を呼び出したのと同じ効果があります。これらの戻り値のみが変更されます。null の場合、状態は変更されません。状態の他のすべての値は保持されます。 🎜

注意すべき点

🎜 初期状態の値を定義する必要があります。 constructor 内、またはクラス属性として。それ以外の場合は、警告が報告されます。 🎜🎜このメソッド getDerivedStateFromProps() は、最初のマウントと再描画中に呼び出されるため、基本的にコンストラクターで受信した props に基づいて setState を行う必要はありません。 🎜🎜getDerivedStateFromProps が定義されている場合、componentWillReceiveProps が定義されます。その後、前者のみが呼び出され、警告が表示されます。 🎜🎜一般的には、状態が更新されるまで特定のコードが呼び出されないようにするためにコールバックを使用します。次に、これらのコードをすべて componentDidUpdate に移動してください。 🎜🎜 static キーワードを使用したくない場合は、次のようにすることができます: 🎜
ComponentName.getDerivedStateFromProps = (nextProps, prevState) => {
  // Your code here
}

Static Mode

严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在React.StrictMode下的组件。它可以用在你的组件树的任何一部分上。

import {StrictMode} from 'react'

class Application extends React.Component {
  render() {
    return (
      <StrictMode>
        <Context.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}

如果一个在StricMode子树里的组件使用了componentWillMount方法,那么你会看到一个报错消息。

AsyncMode

异步模式在React.unsafe_AsyncMode下。使用AsncMode也会打开StrictMode模式下的警告。

相关推荐:

React 16.3之Context API详解


以上がReact 16.3 の新機能の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。