Si une image vaut mille mots, alors une démo interactive doit en valoir... un million ?
Aimez-vous faire défiler les mots à la mode pour comprendre le but d'une application ? Probablement pas. Et je n'avais pas envie d'écrire toutes ces bêtises pour mon dernier projet passionné, Wanna. J'ai donc recherché une solution plus intéressante : imbriquer mon application dans sa propre page de destination que les utilisateurs peuvent explorer !
Grâce à la composabilité de React, nous pouvons presque simplement restituer notre composant racine de l'application et l'arrêter :
export const InteractiveDemo = () => { return ( <App /> ) }
Cependant, vous rencontrerez quelques problèmes :
Résolvons-les. Je veux utiliser React Router v6 et Apollo GraphQL, mais les concepts s'appliquent quelle que soit la technologie.
Pour séparer la navigation de l'application de démonstration de l'application réelle, nous l'enveloppons dans un autre fournisseur de navigation :
+import { MemoryRouter, UNSAFE_LocationContext } from 'react-router' export const InteractiveDemo = () => { return ( + // Hack to nest MemoryRouter inside BrowserRouter. + // https://github.com/remix-run/react-router/issues/7375 + <UNSAFE_LocationContext.Provider value={null}> + <MemoryRouter initialEntries={['/app']}> <App /> + </MemoryRouter> + </UNSAFE_LocationContext.Provider> ) }
Notez que nous utilisons un MemoryRouter afin que le navigateur reste sur la même page pendant que la démo navigue en interne.
Pour fournir à l'application de démonstration de fausses données, nous maintenons un faux "backend" à l'intérieur de l'application client avec useState et le servons via un client ou un serveur fictif (selon l'implémentation). Il est peu invasif pour le reste du code de l'application et nous permet même d'utiliser la démo pour des tests manuels - très pratique lors d'une itération rapide.
J'ai utilisé mock-apollo-client ; pour REST ou tRPC, vous pouvez utiliser quelque chose comme nock. Ils sont destinés aux tests automatisés mais sont exactement ce dont nous avons besoin ici.
Tout d'abord, nous créons un client fictif dont les gestionnaires de requêtes interrogent et modifient les données de démonstration d'une manière qui imite le vrai backend :
import { InMemoryCache } from '@apollo/client' import { createMockClient, createMockSubscription } from 'mock-apollo-client' import { useMemo, useState } from 'react' // GraphQL documents that our client sends to the real server import GET_FRIENDS from '../../gql/getFriends.gql' import ADD_FRIEND from '../../gql/addFriend.gql' // Simplified example export const useDemoClient = () => { const [friends, setFriends] = useState[{ __typename: 'User', id: 1, name: 'Nick', }] // Cache should persist across clients const cache = useMemo(() => { // Should be the same cache configuration you provide to your real Apollo client return new InMemoryCache() }, []) // We need to recreate the mock client whenever the data changes // because it doesn't support resetting request handlers. const mockClient = useMemo(() => { const client = createMockClient({ cache }) client.setRequestHandler(GET_FRIENDS, () => Promise.resolve({ data: { friends: friends } })) client.setRequestHandler(ADD_FRIEND, ({ user }) => { setFriends((prev) => prev.concat([user])) return Promise.resolve({ data: { addFriend: user } }) }) return client }, [friends]) return mockClient }
Ensuite, tout comme nous l'avons fait avec la navigation, nous enveloppons notre démo dans un nouveau fournisseur avec notre client fictif :
+import { ApolloProvider } from '@apollo/client' export const InteractiveDemo = () => { + const demoClient = useDemoClient() return ( + <ApolloProvider client={demoClient}> <UNSAFE_LocationContext.Provider value={null}> <MemoryRouter initialEntries={['/app']}> <App /> </MemoryRouter> </UNSAFE_LocationContext.Provider> + </ApolloProvider> ) }
Si vous utilisiez plutôt un serveur fictif, vous injecteriez son URL dans le vrai client de l'application de démonstration.
Ça marche ! Maintenant, comment faire comprendre à l'utilisateur qu'il visionne une démo interactive ?
Wanna est avant tout mobile, j'ai donc choisi de rendre la démo dans un cadre de téléphone. J'ai utilisé devices.css car il offre les appareils qui me paraissaient les plus beaux (c'est-à-dire un cadre minimal pour maximiser l'espace de démonstration). Mais par souci de simplicité, nous utiliserons ici une bibliothèque qui prend en charge React prête à l'emploi : react-device-frameset.
Utilisons également le zoom pour réduire l'interface utilisateur de démonstration et l'imbriquer joliment dans le reste de la page. Dans Wanna, j'ai dû inverser et tenir compte de ce zoom lors de l'utilisation de
export const InteractiveDemo = () => { return ( <App /> ) }
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!