如果一张图片值一千个字,那么一个交互式演示一定值......一百万?
您喜欢滚动浏览流行语来了解应用程序的用途吗?可能不会。我并不想为我最新的热情项目《Wanna》写那么多废话。因此,我寻求了一个更有趣的解决方案:将我的应用程序嵌套在自己的登陆页面中,供用户探索!
感谢 React 的可组合性,我们几乎简单地渲染我们的根 App 组件并收工:
export const InteractiveDemo = () => { return ( <App /> ) }
但是,您会遇到一些问题:
让我们解决这些问题。想要使用 React Router v6 和 Apollo GraphQL,但无论技术如何,这些概念都适用。
为了将演示应用程序的导航与真实应用程序分开,我们将其包装在另一个导航提供程序中:
+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> ) }
请注意,我们使用 MemoryRouter,以便在演示内部导航时浏览器保持在同一页面上。
为了向演示应用程序提供虚假数据,我们使用 useState 在客户端应用程序内维护一个虚假的“后端”,并通过模拟客户端或服务器(取决于实现)为其提供服务。它对应用程序代码的其余部分影响最小,甚至允许我们使用演示进行手动测试 - 在快速迭代时非常方便。
我使用了mock-apollo-client;对于 REST 或 tRPC,您可以使用类似 nock 的东西。它们用于自动化测试,但正是我们所需要的。
首先,我们创建一个模拟客户端,其请求处理程序以模仿真实后端的方式查询和改变演示数据:
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 }
然后就像我们对导航所做的那样,我们使用模拟客户端将演示包装在新的提供程序中:
+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> ) }
如果您使用模拟服务器,则可以将其 URL 注入演示应用程序的真实客户端。
它有效!现在我们如何让用户清楚地知道他们正在观看交互式演示?
想要移动优先,所以我选择在手机框架内渲染演示。我使用 devices.css 因为它提供了我认为看起来最好的设备(即最小边框以最大化演示空间)。但为了简单起见,这里我们将使用一个支持 React 开箱即用的库:react-device-frameset。
我们还可以使用缩放来缩小演示 UI,并将其很好地嵌套在页面的其余部分中。在 Wanna 中,当使用
export const InteractiveDemo = () => { return ( <App /> ) }
以上是立即吸引用户:在 React SPA 中嵌入交互式演示的详细内容。更多信息请关注PHP中文网其他相关文章!