ホームページ >ウェブフロントエンド >jsチュートリアル >コンテキスト、Redux、それとも合成?

コンテキスト、Redux、それとも合成?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-19 11:28:09629ブラウズ

この投稿は元々、2023 年 2 月 23 日に私のブログ ページで公開されたものです

私は、テクノロジー企業による最近の人員削減の影響を受けた開発者の一人です。そこで、react でフロントエンドのポジションの面接を受け始めました。

ある会社で、私は React における古典的なプロップドリルの問題を与えられました。
そしてそれを解決するように求められました。物事を簡単にするために、与えられた問題は次のようなものでした
これ:

export default function App() {
  const [user, setUser] = React.useState(null);

  const handleLogin = () => setUser(userDetails);

  return (
    <div className="App">
      Company Logo
      <div>
        {user ? (
          <Dashboard user={user} />
        ) : (
          <button onClick={handleLogin}>Login</button>
        )}
      </div>
    </div>
  );
}

function Dashboard({ user }) {
  return (
    <div>
      <DashboardNav user={user} />
    </div>
  );
}

function DashboardNav({ user }) {
  return (
    <div>
      <WelcomeUser user={user} />
      <UserRole user={user} />
    </div>
  );
}

function WelcomeUser({ user }) {
  return <div>Welcome {user.name}</div>;
}

function UserRole({ user }) {
  return <div>Role {user.role}</div>;
}

ご覧のとおり、ユーザープロパティを App コンポーネントから
に渡しています。 子コンポーネント WelcomeUser および UserRole。中間コンポーネントである Dashboard と DashboardNav は、props を転送するだけであり、実際には使用しません。

Context, Redux or Composition?

これは、React における古典的な プロップ ドリル の問題です。

興味深いことに、インタビュアーは React Context API のいずれかを使用して問題を解決するよう求めました
または Redux を使用します。

React コンテキストによる解決

コンテキスト API を使用してこの問題を解決すると、以下のコードのようになります。

const UserContext = React.createContext(undefined);

export default function App() {
  const [user, setUser] = React.useState(null);

  const handleLogin = () => setUser(userDetails);

  return (
    <div className="App">
      Company Logo: Context
      <div>
        {user ? (
          <UserContext.Provider value={user}>
            <Dashboard />
          </UserContext.Provider>
        ) : (
          <button onClick={handleLogin}>Login</button>
        )}
      </div>
    </div>
  );
}

function Dashboard() {
  return (
    <div>
      <DashboardNav />
    </div>
  );
}

function DashboardNav() {
  return (
    <div>
      <WelcomeUser />
      <UserRole />
    </div>
  );
}

function WelcomeUser() {
  const user = React.useContext(UserContext);
  return <div>Welcome {user.name}</div>;
}

function UserRole() {
  const user = React.useContext(UserContext);
  return <div>Role {user.role}</div>;
}

UserContext を作成し、プロバイダーでダッシュボードをラップしています。
必要なプロパティを深くネストされた子コンポーネントに渡すことができます。この解決策
動作します。

Context, Redux or Composition?

Reduxによる解決

したがって、古典的な Redux ルートを進む場合は、同様の
を作成する必要があります。 を構造化し、ユーザー
を含む単一のグローバル ストアですべてをラップします。 物体。


には redux を使用しているため、ソリューション コードには大量の定型文が含まれることになります。 簡単な問題を解決します。

以下にコードの要点を示しましたが、実際に完全に調べたい場合は、
コード、どうぞ: redux で解決します。

export default function App() {
  return (
    <Provider store={store}>
      <ReduxConnectedApp />
    </Provider>
  );
}

function ReduxApp({ user, setUser }) {
  const handleLogin = () => setUser(userDetails);

  return (
    <div className="App">
      Company Logo: Redux
      <div>
        {user ? <Dashboard /> : <button onClick={handleLogin}>Login</button>}
      </div>
    </div>
  );
}


function Dashboard() {
  return (
    <div>
      <DashboardNav />
    </div>
  );
}

function DashboardNav() {
  return (
    <div>
      <ConnectedWelcomeUser />
      <ConnectedUserRole />
    </div>
  );
}

function WelcomeUser({ user }) {
  return <div>Welcome {user.name}</div>;
}

const mapStateToPropsWelcomeUser = (state) => ({ user: state });
const ConnectedWelcomeUser = connect(mapStateToPropsWelcomeUser)(WelcomeUser);

function UserRole({ user }) {
  return <div>Role {user.role}</div>;
}

const mapStateToPropsUserRole = (state) => ({ user: state });
const ConnectedUserRole = connect(mapStateToPropsUserRole)(UserRole);

グローバル状態へのアクセスが必要なコンポーネントを接続しました
redux に保存されます。

どうやって解決したか

反応構成について読んだので、次のようにして問題を解決しました
子プロップの使用は次のようになります

export default function AppSolution() {
  const [user, setUser] = React.useState(null);

  const handleLogin = () => setUser(userDetails);

  return (
    <div className="App">
      Company Logo
      <div>
        {user ? (
          <Dashboard>
            <DashboardNav>
              <WelcomeUser user={user} />
              <UserRole user={user} />
            </DashboardNav>
          </Dashboard>
        ) : (
          <button onClick={handleLogin}>Login</button>
        )}
      </div>
    </div>
  );
}

function Dashboard({ children }) {
  return <div>{children}</div>;
}

function DashboardNav({ children }) {
  return <div>{children}</div>;
}

function WelcomeUser({ user }) {
  return <div>Welcome {user.name}</div>;
}

function UserRole({ user }) {
  return <div>Role {user.role}</div>;
}

考えてみれば、これは導入せずにこの問題を解決する簡単な方法です
createContextやreact-reduxなどの複雑さ。その他にも次のような特典があります

として
  • 将来的に、ダッシュボード内に状態を導入して操作すると、 DashboardNav は再レンダリングされません。
  • 必要なコンポーネントにのみ小道具を提供することで、良好な可視性が得られます。 ユーザーのすべてのコンシューマーのコンポーネント (ファイル) 間を移動する必要がなく、 探してください。

このパターンは新しいものではなく、すでに反応コミュニティで話題になっています。そのような優れたチュートリアルの 1 つは、React でコンポジションを使用して「プロップ ドリル」を回避することです

結論

しかし、面接官からのフィードバックは次のとおりです

インタビュー対象者は問題を正しく理解しておらず、期待された解決策を提供できませんでした。

その理由は、面接官がこのパターンに気づいていないか、私が求められていない方法で問題を解決しようとしたかのどちらかだと思います。

そうは言っても、私は今、react の興味深いパターンについてもっと書きたいと思っています。それがより多くの読者に届くことを願っています。

この記事を共有して、ご意見をお聞かせください。


参考文献

  • コードサンドボックス ソリューション
  • コンテキストを使用する前に - React Docs
  • React でコンポジションを使用して「プロップドリル」を回避する
  • ブログに掲載された回答: React レンダリング動作の (ほぼ) 完全なガイド
  • ブログに掲載された回答: React Context が「状態管理」ツールではない理由 (そして Redux に代わらない理由)

以上がコンテキスト、Redux、それとも合成?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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