[フロントエンド面接の質問] 2023 年のフロントエンド面接の質問 - React

人の人生には必ず浮き沈みがあります。常に日の出のように昇るわけではありませんし、常に惨めな状態になるわけでもありません。アップダウンの繰り返しが人間の修行となる。したがって、上に浮いている人は誇る必要はありませんし、下に沈んでいる人は悲観する必要はありません。私たちは率直かつ謙虚、楽観的かつ進取的であり、前進しなければなりません。——松下幸之助

こんにちは、私の名前はジャン・チェンです。今日のインターネット環境では、誰もが多かれ少なかれ感じているはずです。この衝動的な社会において、常に自分の人格を維持することによってのみ、人はさまざまな利益を認識し、お互いを励まし合うことができます。

2023 年の最新の面接質問を集めたので、常に準備してください。

この記事は、WeChat パブリック アカウントで最初に公開されました: Wild Programmer Jiang Chen

誰でも「いいね!」「収集」「フォロー」大歓迎です

記事一覧

状態マネージャーをいつ使用するか?

プロジェクトの全体構造の観点から、プロジェクトの背景に応じたスピードを選択する必要があります。プロジェクトの背景がステータスマネージャーの使用に適していない場合は、WeChat アプレットなど、以下の観点から見ることができるなど、ステータスマネージャーを使用する必要性は必ずしもありません。

ユーザーの使い方は複雑です

  • 異なるIDを持つユーザーは異なる使用方法を持っています(一般ユーザーと管理者など)
  • 複数のユーザー間のコラボレーションが可能
  • サーバーと頻繁にやり取りするか、WebSocket を使用する
  • View は複数のソースからデータを取得する必要があります

コンポーネントの観点から見ると

  • 特定のコンポーネントの状態を共有する必要がある
  • 特定の状態をどこからでも利用できる必要がある
  • コンポーネントはグローバル状態を変更する必要があります
  • あるコンポーネントが別のコンポーネントの状態を変更する必要がある

レンダリングハイジャックとは何ですか?

レンダリング ハイジャックとは何ですか? レンダリング ハイジャックの概念は、コンポーネントの出力を別のコンポーネントから制御する機能です。もちろん、この概念は一般に、react の高次コンポーネント (HOC) と併せてより明確に説明されます。

上位コンポーネントは、元のコンポーネントのレンダリング出力を制御するために render 関数で多くの操作を実行できますが、元のコンポーネントのレンダリングが変更される限り、これを一種のレンダリング ハイジャックと呼びます。

実際、上位コンポーネントでは結合レンダリングと条件付きレンダリングはどちらもレンダリングハイジャックの一種ですが、逆継承することで上記2点を実現できるだけでなく、元のコンポーネントのrender関数で生成したReact要素も継承することができます。強化される。

実際の操作では、state や props を操作することでレンダリングハイジャックを実現できます。

React コンポーネントの国際化を実現するにはどうすればよいですか?

i18next に依存するソリューションには、大規模なビジネス プロジェクトにとって非常に厄介な問題があります。それは、json ファイルのメンテナンスです。製品のイテレーションごとに新しい構成を追加する必要があるため、この構成を誰が保守するのか、どのように保守するのかによって多くの問題が発生します。また、プロジェクトで数十の言語をサポートする必要がある場合、これらの数十のドキュメントはどうなりますか?

したがって、現在、大規模メーカーの間でより一般的なソリューションは AST を使用することです。新しいバージョンが開発されるたびに、コード内の中国語を見つけるためにすべてのコードが AST によってスキャンされます。中国語がキーとして使用され、インテリジェントな翻訳サービスが使用されます。 project.json ファイルを自動的に生成するために呼び出されます。このようにして、人間が json ファイルを管理する必要はなくなり、すべてが自動化ツールに依存します。現時点では、滴滴出行の di18n やアリババの kiwi など、大手メーカーのオープンソースがすでに存在しています。

React はコード分割をどのように行うのでしょうか? 分割の原理は何ですか?

反応分割の前提条件は、コードディレクトリ設計仕様、モジュール定義仕様、コード設計仕様、および高い凝集性、低い結合性などのプログラム設計の一般原則への準拠であると思います。

私たちの反応プロジェクトでは:

  • API レベルでは、これを個別にカプセル化し、http リクエストの結果を外部に公開します。
  • データ層では、mobx カプセル化を使用して、非同期リクエストとビジネス ロジック処理を処理します。
  • ビュー レイヤーで、mobx レイヤーから渡されたデータを使用してロジックを変更してみます。
  • 静的型リソースは別配置
  • パブリックコンポーネント、上位コンポーネント、プラグインを別々に配置
  • ツールファイルは別々に配置されます

React のどこでエラーをキャッチすればよいでしょうか?

公式ウェブサイトの例:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能够显示降级后的 UI
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // 你同样可以将错误日志上报给服务器
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 你可以自定义降级后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

使用

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

ただし、エラー境界はキャッチされません。

try{}catch(err){}
///异步代码(例如 setTimeout 或 requestAnimationFrame 回调函数)
///服务端渲染
///它自身抛出来的错误(并非它的子组件)

React の props はなぜ読み取り専用なのでしょうか?

React の一方向のデータ フローを保証する設計パターンにより、状態がより予測可能になります。自己コンポーネントの変更が許可されている場合、親コンポーネントは状態をいくつかのサブコンポーネントに渡します。これらのサブコンポーネントが任意に変更されると、それは完全に予測不可能になります。状態がどこで変更されるかはわかりません。純粋な関数のようにプロパティが変更されないように保護する必要があります。

フックを使用してサーバー側のデータを取得するにはどうすればよいですか?

import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
  const [data, setData] = useState({ hits: [] });
  useEffect(async () => {
    const result = await axios(
      'https://api/url/to/data',
    );
    setData(result.data);
  });
  return (
    <ul>
      {data.hits.map(item => (
        <li key={item.objectID}>
          <a href={item.url}>{item.title}</a>
        </li>
      ))}
    </ul>
  );
}
export default App;

フックを使用する場合、どのような原則に従う必要がありますか?

  1. 最上位レベルでのみフックを使用する

ループ、条件分岐、またはネストされた関数内でフックを呼び出さないでください。常に React 関数の最上位で呼び出すようにしてください。

  1. React 関数でのみフックを呼び出します

通常の JavaScript 関数でフックを呼び出さないでください。あなたはできる:

  • ✅ React関数コンポーネントでフックを呼び出す
  • ✅ カスタムフックで他のフックを呼び出す

React Fiber はどのような問題を解決するために設計されていますか?

React15StackReconcilerソリューションの再帰中断不可能の問題により、Diff 時間 (JS 計算時間) が長すぎると、ページ UI (入力ボックスなど) が応答しなくなり、ページ UIvdomに適用できなくなりますdom

この問題を解決するために、React16 では、タスク優先度の考え方により、優先度の高いタスクが入ると中断する新しいrequestIdleCallbackスケジューラを実装しました (互換性と安定性の問題のためrequestIdleCallback、私が独自に実装しました) polyfillreconciler

この新しいスケジューラに適応するために、FiberReconciler元のツリー構造 (vdom) をファイバー リンク リスト (子/兄弟/リターン) の形式に変換するために開始されました。ファイバー トラバーサル全体は、再帰ではなくループに基づいており、次のようにすることができます。いつでも中断されます。

さらに重要なのは、ファイバーベースのリンク リスト構造には、その後の (React 17 レーン アーキテクチャの) 非同期レンダリングと (可能な) ワーカー計算のための非常に優れたアプリケーション基盤があることです。

React のベスト プラクティスは何だと思いますか教えてください

公式サイト参照

なぜ React にはフックが必要なのでしょうか?

公式サイトの回答:

モチベーション

フックは、5 年間に及ぶ数千のコンポーネントの作成と保守の中で私たちが遭遇した、一見無関係に見えるさまざまな問題を解決します。React を学習している方、毎日使用している方、または React と同様のコンポーネント モデルを持つ別のフレームワークを試してみたいと考えている方は、これらの問題に精通しているかもしれません。

コンポーネント間で状態ロジックを再利用するのは困難

React は、再利用可能な動作をコンポーネントに「添付」する方法 (コンポーネントをストアに接続するなど) を提供しません。React をしばらく使用している場合は、レンダー プロップや高次コンポーネントなど、この問題に対するいくつかの解決策に精通しているかもしれません。ただし、そのようなソリューションではコンポーネント構造を再編成する必要があるため、煩雑になり、コードが理解しにくくなる可能性があります。React DevTools で React アプリケーションを観察すると、プロバイダー、コンシューマー、上位コンポーネント、レンダー プロップ、その他の抽象化レイヤーで構成されるコンポーネントが「ネストされた地獄」を形成していることがわかります。DevTools でそれらを除外することはできますが、これはより深い問題を示しています。React は共有状態ロジックのためのより優れたネイティブな方法を提供する必要があります。

フックを使用してコンポーネントから状態ロジックを抽出すると、ロジックを個別にテストして再利用できます。フックを使用すると、コンポーネントの構造を変更せずに状態ロジックを再利用できます。これにより、コンポーネント間またはコミュニティ内でフックを共有することが容易になります。

複雑なコンポーネントを理解するのが難しくなる

私たちはいくつかのコンポーネントを保守することがよくありますが、コンポーネントは最初は単純ですが、徐々に状態ロジックと副作用で埋め尽くされていきます。各ライフサイクルには、多くの場合、無関係なロジックが含まれています。たとえば、コンポーネントは多くの場合、componentDidMount およびcomponentDidUpdate でデータを取得します。ただし、同じcomponentDidMountには、イベントリスニングの設定など、他の多くのロジックも含まれている場合があり、これらのロジックはcomponentWillUnmountでクリアする必要があります。関連していて変更が必要なコードは分割され、まったく関係のないコードは同じメソッドに結合されます。これにより、バグや論理的矛盾が発生しやすくなります。

ほとんどの場合、ステートフル ロジックがあらゆる場所に存在するため、コンポーネントをより小さな粒度に分割することはできません。これはテストに特定の課題ももたらします。同時に、これが、多くの人が React を状態管理ライブラリとともに使用する理由の 1 つです。ただし、多くの場合、これには多くの抽象的な概念が導入され、異なるファイル間を行き来する必要があるため、再利用がより困難になります。

この問題を解決するために、フックは、コンポーネントの相互に関連する部分を、ライフサイクルに従って強制的に分割するのではなく、より小さな機能 (サブスクリプションの設定やデータの要求など) に分割します。リデューサーを使用してコンポーネントの内部状態を管理し、予測しやすくすることもできます。

理解できない授業

コードの再利用とコード管理で遭遇する困難に加えて、クラスが React の学習にとって大きな障壁であることもわかりました。他の言語とは大きく異なる JavaScript でこれがどのように機能するかを理解する必要があります。イベントハンドラーをバインドすることを忘れないでください。安定した構文の提案はなく、コードは非常に冗長です。誰もが props、state、およびトップダウンのデータ フローをよく理解できますが、クラスについては理解できません。経験豊富な React 開発者の間でも、関数コンポーネントとクラス コンポーネントの違い、さらには 2 つのコンポーネントの使用シナリオについてさえ意見の相違があります。

また、React はリリースされてから 5 年が経ちますが、今後 5 年間も時代に遅れないように期待しています。Svelte、Angular、Glimmer などのライブラリが示しているように、コンポーネントのプリコンパイルには大きな可能性があります。特にテンプレートに限定されない場合はそうです。最近、Prepack を使用してコンポーネントの折りたたみを実験し、初期の結果を達成しました。しかし、クラス コンポーネントを使用すると、開発者が最適化手段を無効にするソリューションの使用を誤って奨励してしまうことがわかりました。また、クラスは現在のツールにいくつかの問題を引き起こします。たとえば、クラスは適切に圧縮されず、ホット リロードが不安定になる可能性があります。したがって、コードの最適化を容易にする API を提供したいと考えました。

これらの問題を解決するために、フックを使用すると、クラスなしでさらに多くの React 機能を使用できるようになります。概念的には、React コンポーネントは常に関数に似ています。フックは、React の精神的な原則を犠牲にすることなく機能を取り入れています。フックは、複雑な関数型プログラミングやリアクティブ プログラミングのテクニックを学ばなくても、問題の解決策を提供します。

状態管理はどのような問題を解決しますか?

ビューレイヤーに焦点を当てる

Reactの公式サイトのご紹介です。ユーザーインターフェースを構築するためのJavaScriptライブラリ ビュー層を中心とした特徴から万能フレームワークとはいえない Angularなどの万能フレームワークと比べて、Reactはシンプルかつ単機能である。たとえば、フロントエンドのルーティング、状態管理、ワンストップの開発ドキュメントなどはありません。

f(状態) = ビュー

React コンポーネントは、状態を入力してビューを出力する関数と同様に、状態 (またはプロパティ) に基づいてページをレンダリングします。ただし、これは完全な意味での MDV (Model Driven View) ではなく、完全なモデル層はありません。ちなみに、現在フロントエンド開発ではコンポーネント化やMDVが流行っていて、それが全体的な傾向になっているような気がします…。

状態は上から下に流れます。Prop は読み取り専用です。

私たちは最初に React を書き始めたときからこの機能を理解していました。状態の流れの方向はコンポーネントの外側から内側、上から下であり、渡される props は読み取り専用です。props を変更したい場合は、パッケージ化された setState メソッドを上部から渡すだけです。成分。ng-model を備えた angular とは異なり、vue には双方向バインディング命令を提供する v-model があります。これは React の規則です。面倒だと思うかもしれませんが、状態の流れはより明確です。大規模なスパでは、一方向のデータ フローの方が常に快適です。

これらの特性により、React 自体は強力な状態管理機能を提供していません。ネイティブ メソッドは大きく 3 つあります。

機能コンポーネントにはライフサイクルがありますか?

React.component を継承するクラス コンポーネントとは異なり、ライフ サイクルの概念が提供されていないため、ライフ サイクルを使用して関連する概念を特に強調することができます。

不変の原理とは何ですか?

ディクショナリ ツリーを使用してデータ構造を永続化し、オブジェクト生成ロジックを最適化し、更新時のコストを削減します。

HTML がエスケープされないようにするにはどうすればよいですか?

dangerouslySetInnerHTML

コンポーネントのレンダリング効率を向上させる方法を教えてください

与える

とは

React は、仮想 DOM と効率的な Diff アルゴリズムの完璧な組み合わせに基づいており、DOM の最小粒度更新を実現します。ほとんどの場合、React の DOM レンダリング効率は、日常業務には十分です。

複雑なビジネス シナリオでは、依然としてパフォーマンスの問題が私たちを悩ませます。現時点では、実行パフォーマンスを向上させるためにいくつかの対策を講じる必要があり、不必要なレンダリングを回避することは、ビジネスにおける一般的な最適化手法の 1 つです。

実行する方法

クラスコンポーネント:
  • Pureコンポーネントの継承
  • shouldComponentUpdate を使用して最適化する
機能コンポーネント:
  • メモは PureComponent をシミュレートします
  • useMemo を使用して変数をキャッシュする
  • useCallbackキャッシュ関数を使用する
  • ループ内にキーを追加します。キーには配列項目の一意の値を使用するのが最善です。インデックスは推奨されません。

要約する

実際の開発プロセスでは、フロントエンドのパフォーマンスの問題が考慮しなければならない問題ですが、ビジネスが複雑になればなるほど、パフォーマンスの問題が発生する確率も高くなります。

さらに、ページをより小さな粒度に細分化することをお勧めします。粒度が大きすぎると、状態が変更されたときに、大きなコンポーネント全体がレンダリングされます。コンポーネントが分割された後、粒度は小さくなり、サブコンポーネントの不必要なレンダリングを削減する機能

高次コンポーネント (HOC) についての理解について話してください。

高階関数、以下の条件の少なくとも 1 つを満たす関数

  • 1 つ以上の関数を入力として受け入れます
  • 関数を出力する

React では、上位コンポーネントは 1 つ以上のコンポーネントをパラメータとして受け取り、コンポーネントを返します。これは本質的にはコンポーネントではなく関数です。

const EnhancedComponent = highOrderComponent(WrappedComponent);

上記のコードでは、関数はコンポーネントをWrappedComponentパラメーターとして受け取り、処理された新しいコンポーネントを返します。EnhancedComponent

この高次コンポーネントの実装は、本質的にデコレータ設計パターンです。

React refs についての理解について教えてください。

RefはコンピュータではResilient File System(英語:Resilient File System、ReFSと呼ばれる)と呼ばれています。

React の Ref は、render メソッドで作成された DOM ノードまたは React 要素にアクセスする方法を提供します。

これは本質的に ReactDOM.render() によって返されるコンポーネント インスタンスです。レンダリング コンポーネントの場合はコンポーネント インスタンスを返し、dom をレンダリングする場合は特定の dom ノードを返します。

クラス

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref="myref" />;
  }
}

フック

function App(props) {
  const myref = useRef()
  return (
    <>
      <div ref={myref}></div>
    </>
  )
}

おすすめ

転載: blog.csdn.net/weixin_42439919/article/details/133065905
おすすめ