Maison >interface Web >js tutoriel >Contexte, redux ou composition ?
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.
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.
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.
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.
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
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 »
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
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!