React Hook sは深く入り込みます.


このタイトルはあまりよくないかもしれませんが、この文章は確かに教程を使っているのではなく、多すぎる点をカバーしていません.時間に余裕があるのか、それとも公式文書を完全に見るべきです.
React Hooksは一部の人にとってはまだ馴染みのない言葉かもしれませんが、やはり今のReactコミュニティで一番人気のある言葉になりました.
最初にこれを知ったのですが、Dan Abrameovは10月末にツイートしました.Making Sense of React Hookです.見たことがない方に先に読んでください.第一印象は「Reactはもともとこうあるべきだった」ということです.
この文章を読んでから、全体的にHooksに対して認識してもらいたいです.そしてデザイン哲学に対して理解があります.見たい過程は焦らないでください.私の考えに沿って歩きます.
もしあなたが自分で文章について一緒に練習したいなら、reactreact-domに更新されました.16.7.0-alpha以上、ESLintが配置されている場合は、対応するPluginを追加してください.
挿入歌
長い間、多くの人がStateless ComponentFunctional Componentを混同しています.これは違うと彼らに説明してみます.でも、Functional Componentの中では確かにstateは使えませんでした.いくら説明しても力がありません.まさかこの冥冥の中には、React Hookのようなものが現れるという暗示がありますか?
React Hooksの本質
少し複雑な項目は必ず大量のReactライフサイクル関数(状態管理ライブラリを使ってもこれは避けられないので注意してください)が溢れています.ライフサイクルごとに、ある業務ロジックの一部をほとんど担っています.あるいは、ある業務ロジックは各ライフサイクルに分散しています.
Hooksの出現の本質はこのようなライフサイクル向けプログラミングをビジネスロジック向けプログラミングに変えています.これ以上関心すべきでないライフサイクルに関心を持たなくてもいいです.
Hooksの進化
まず一般的な需要を想定して、Modalにはいくつかの情報を展示する必要があります.これらの情報はAPIを通じて入手し、Modalの強い業務と関連している必要があります.
  • 業務が簡単なため、追加の状態管理ライブラリを導入していません.
  • 業務が強いので、データとコンポーネントを分けてオープンしたくないです.
  • APIデータはランダムに変動しますので、Modalを開くたびに最新のデータ
  • を取得する必要があります.
  • 後期最適化のために、追加のコンポーネントの作成と廃棄があってはいけません.
    私達の可能な実現は以下の通りです.
    コード完全デモンストレーションアドレス
    class RandomUserModal extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          user: {},
          loading: false,
        };
        this.fetchData = this.fetchData.bind(this);
      }
    
      componentDidMount() {
        if (this.props.visible) {
          this.fetchData();
        }
      }
    
      componentDidUpdate(prevProps) {
        if (!prevProps.visible && this.props.visible) {
          this.fetchData();
        }
      }
    
      fetchData() {
        this.setState({ loading: true });
        fetch('https://randomuser.me/api/')
          .then(res => res.json())
          .then(json => this.setState({
            user: json.results[0],
            loading: false,
          }));
      }
    
      render() {
        const user = this.state.user;
        return (
          
            
            {this.state.loading ?
              
    loading...
    :
    • Name: {`${(user.name || {}).first} ${(user.name || {}).last}`}
    • Gender: {user.gender}
    • Phone: {user.phone}
    }
    ) } }
    私たちは、親のコンポーネントによって制御されるかどうかを示すトラフィック論理を含むRandomUserModalを抽象化し、したがって、パラメータvisibleおよびhandleCloseModalに入る.
    Modalが開いたときにデータを取得するためには、componentDidMountcomponentDidUpdateの2つのライフサイクルでデータ取得の論理を実現する必要があります.また、constructorのいくつかの初期化動作も欠かせません.
    実は私達の要求は簡単です.APIを通じて新しい情報を取得します.これは抽象的に出てくる業務ロジックです.この業務ロジックがReactで正確に働くために、Reactコンポーネントのライフサイクルによって分解しなければなりません.この分解はコード冗長性に加えて多重化も難しい.
    Hooksを改造したらどうなりますか?
    完全なプレゼンテーションアドレス
    function RandomUserModal(props) {
      const [user, setUser] = React.useState({});
      const [loading, setLoading] = React.useState(false);
    
      React.useEffect(() => {
        if (!props.visible) return;
        setLoading(true);
        fetch('https://randomuser.me/api/').then(res => res.json()).then(json => {
          setUser(json.results[0]);
          setLoading(false);
        });
      }, [props.visible]);
      
      return (
        // View          
      );
    }
    明らかに、Class形式をFunction形式に変えて、二つのState Hookを使ってデータ管理を行いました.以前はconstructorcDMのライフサイクルでした.私たちは直接にEffect Hookでやりました.これらを行うと、最大の利点はコードの簡素化であり、ビジネスロジックがコンパクトになり、コードの行数も50+行から30+行に減少します.
    Hooksの強みはこれだけではなく、最も重要なのはこれらの業務ロジックが勝手に引き抜けます.普通の関数と変わらないです.具体的には次の更なる改造を見てもいいです.
    完全なプレゼンテーションアドレス
    //     Hook
    function useFetchUser(visible) {
      const [user, setUser] = React.useState({});
      const [loading, setLoading] = React.useState(false);
      
      React.useEffect(() => {
        if (!visible) return;
        setLoading(true);
        fetch('https://randomuser.me/api/').then(res => res.json()).then(json => {
          setUser(json.results[0]);
          setLoading(false);
        });
      }, [visible]);
      return { user, loading };
    }
    
    function RandomUserModal(props) {
      const { user, loading } = useFetchUser(props.visible);
      
      return (
        //      
      );
    }
    ここのcDUはカスタムHookです.その地位は自分の持っているuseFetchUserと同じです.他のコンポーネントでも使えます.このコンポーネントでも二回使って、自然に離れます.
    トラヒックロジック多重化
    ここで述べたトラヒック論理多重は、主にライフサイクルを必要とするトラヒックロジックである.コンポーネントの積み重ねだけでコードを組織しても、さまざまな多重化の目的が達成できますが、コンポーネントが非常に複雑になり、データの流れが乱れます.コンポーネント集積はUIレイアウトに適していますが、論理組織には適していません.これらの問題を解決するために、Reactの発展の過程で、多くの解決策が生まれました.
    ミxins
    悪いところがはるかに大きいのは持ってきた利益です.今はもう支持しないので、多くは言いません.この文章を見てもいいです.Mixins Consed Harmful.
    Class Inherityance
    公式はこのやり方を勧めません.実は私も実際に見たことがありません.
    High-Order Components(HOC)
    React高次コンポーネントはパッケージ業務のコンポーネントではほとんど何度もテストされています.その実現は自分を関数として受け入れ、もう一つのコンポーネントを返します.このようにして、いくつかの業務ロジックをまとめて処理し、多重化の目的を達成することができます.
    一般的な比較の一つはuseStatereact-redux関数です.
    (写真はここから)
    しかし、多くの人が問題にはまっています.
    (写真はここから)
    Render Props
    Render Propsは実はよくあります.例えば、React Context API:
    class App extends React.Component {
      render() {
        return (
          
            
              {val => 
    {val}
    }
    ) } }
    その実現の構想はとても簡単で、もとは「部品」のところに置くべきだったということをリフローに変えました.このようにして、現在のコンポーネントの中でサブアセンブリの状態を取って、使うことができます.
    しかし、同じようにWrapper Hell問題が発生します.
    (写真はここから)
    Hooks
    Hooksは本質的にはライフサイクル向けプログラミングをビジネスロジック向けプログラミングに変えたと言っていますが、書き方による最適化はついでです.
    ここで、クラス比をすると、connectは本質的にJSの中で非同期のプログラミング思惟を同期の思惟に変えたので、書き方の上で表現した特徴は元のCallback Hellが引き分けされました.
    要約の比較:
  • await/asyncはCallback Hellを外しました.非同期プログラミング思惟は同期プログラミング思惟
  • になりました.
  • Hook sはWrapper Hellを消し、ライフサイクル向けプログラミングは業務ロジック向けプログラミング
  • になりました.
    ここでは客観的に言わなければならない.HOCとRender Propsはやはり存在する必要があり、React Classをサポートする一方で、純粋な論理パッケージだけでなく、論理+コンポーネントのパッケージシーンにも適していることが多い.また、上記の非難の最大の問題はWrapper Hellです.私はFragmentを使っても基本的に解決できると思います.
    状態ボックス
    まず、React Hook sのデザインは直感に反していますが、なぜこう言いますか?まず自分に聞いてみてもいいです.なぜHooksは他のHooksの関数やReact Functionのコンポーネントにしかないですか?
    私達の認知の中で、Reactコミュニティはずっと関数式、純粋な関数などの思想を尊重して、Hooks概念を導入した後のawait/asyncはもう純粋でなくなりました.Functional Componentは実行文というより、声明です.声明はここに「状態箱」が置いてあります.箱には入力と出力があります.残りの内部実装は何も分かりません.重要なのは、箱には記憶があります.次にこの位置を実行する時、前の文脈情報があります.
    類比「コード」と「プログラム」の違いは前者が死に、後者が生きています.表式useXxxc = a + baとを積算した値をbに割り当てることを表していますが、cと書くとc := a + bcとが加算されることを表しています.表現は似ているように見えますが、実際には、後者は時間の次元を隠しています.それは単に演算ではなく連絡を表しています.これはRxJSなどの倉庫で多く使われています.
    このような声明は、現在弱いaプレフィックスによって識別されている(しかし、設計上は多くの簡潔である)が、各箱と状態の対応関係を間違えないように書くときには、Hooksはbを先頭にして、トップの機能領域に置く必要があり、つまりuseなどを包むことができない.文章の冒頭にそのESLint Pluginを導入すれば、間違いを心配することはありません.
    締め括りをつける
    この文章にはきちんとしたディレクトリ構造がないかもしれません.ほとんどは個人的な理解と関連した思考です.したがって、これは本物の文書を見に行く代わりに、もっと多くのことを知ることができません.もしあなたが読み終わったら、やはり無駄話が多すぎると思います.何を言っているのか分かりません.少なくとも次の点で作者と共鳴してほしいです.
  • Hookの本質はライフサイクル向けプログラミングをビジネスロジック向けプログラミングに変えました.
  • Hook sは論理状態ボックスを使用しています.入出力は連絡先を表しています.
  • HooksはReactの未来ですが、元のクラスを完全に代替することはできません.
  • 参照
  • https://reactjs.org
  • 文章は自由に転載できますが、この原文のリンクを残してください.
    情熱的なあなたがES 2049 Studioに参加することを歓迎します.履歴書はcaijun.hcj(at)aliba-i-nc.comに送ってください.