Maison >interface Web >js tutoriel >Contexte, redux ou composition ?

Contexte, redux ou composition ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-19 11:28:09626parcourir

Cet article a été initialement publié le 23 février 2023 sur ma page de blog

J'étais l'un des développeurs qui ont été touchés par les récents licenciements d'entreprises technologiques. J'ai donc commencé à donner des entretiens pour des postes frontend avec React.

Dans l'une des entreprises, on m'a posé un problème classique de forage d'hélices en réaction,
et on lui a demandé de le résoudre. Pour garder les choses simples, le problème posé était comme
ceci :

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>;
}

Comme vous pouvez le constater, nous transmettons l'accessoire utilisateur du composant App au
composants enfants WelcomeUser et UserRole. Les composants intermédiaires Dashboard et DashboardNav ne font que transmettre les accessoires et ne les utilisent pas vraiment.

Context, Redux or Composition?

Il s'agit d'un problème classique de perçage d'accessoires en réaction.

Fait intéressant, l'intervieweur a demandé de résoudre le problème soit par l'API React Context
ou en utilisant Redux.

Résolution par contexte React

L'utilisation de l'API contextuelle pour résoudre ce problème ressemblerait au code ci-dessous.

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>;
}

Nous créons UserContext et encapsulons le tableau de bord avec le fournisseur, de sorte que
nous pouvons transmettre les accessoires que nous voulons à un composant enfant profondément imbriqué. Cette solution
fonctionne.

Context, Redux or Composition?

Résolution par Redux

Donc, si nous suivons la voie classique du redux, nous devons créer un
similaire structurer et envelopper le tout dans un seul magasin global, qui contient l'utilisateur
objet.

Le code de la solution contiendrait une tonne de passe-partout, car nous utilisons redux pour
résoudre un problème simple.

Je viens de donner l'essentiel du code ci-dessous, mais si vous voulez vraiment en explorer l'intégralité
code, voilà : résoudre avec 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);

Nous avons connecté les composants qui doivent accéder à l'état global
stocké dans Redux.

Comment je l'ai résolu

Après avoir lu sur la composition des réactions, j'ai résolu le problème en créant
utilisation d'un accessoire pour enfants, qui ressemblait à ceci

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>;
}

Si vous y réfléchissez, c'est le moyen le plus simple de résoudre ce problème sans introduire
toute complexité comme createContext ou réagir-redux. Nous bénéficions également d'autres avantages tels
comme

  • À l'avenir, si nous introduisons un état dans Dashboard et le manipulons, notre DashboardNav n'est jamais restitué.
  • En fournissant les accessoires uniquement aux composants requis, nous avons une bonne visibilité de tous les consommateurs de l'utilisateur, sans avoir à naviguer entre les composants (fichiers) pour cherchez-les.

Ce modèle n'est pas nouveau, et il a déjà été évoqué dans la communauté React. Une de ces bonnes procédures pas à pas consiste à utiliser la composition dans React pour éviter le « Prop Drilling »

Conclusion

Cependant, j'ai reçu les commentaires de l'intervieweur, et ça se passe comme ça

La personne interrogée n'a pas bien compris le problème et n'a pas été en mesure d'apporter la solution attendue.

Je suppose que la raison est soit que l'intervieweur n'était pas au courant de ce schéma, soit que j'ai choisi de résoudre le problème d'une manière qui n'avait pas été demandée.

Cela dit, je suis maintenant motivé pour écrire davantage sur les modèles intéressants de React, en espérant que cela atteigne un public plus large.

Faites-moi savoir ce que vous pensez en partageant cet article.


Références

  • Solution Codesandbox
  • Avant d'utiliser le contexte - React Docs
  • Utiliser la composition dans React pour éviter le "Prop Drilling"
  • Réponses bloguées : un guide (essentiellement) complet sur le comportement de rendu de React
  • Réponses bloguées : Pourquoi React Context n'est pas un outil de « gestion d'état » (et pourquoi il ne remplace pas Redux)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn