在React Native上创建移动聊天应用程序

这是本文的第二部分( 此处为第一部分),致力于使用apollo-server-koa和react-native创建聊天。 它将涵盖移动聊天应用程序的创建。 在上一部分中,已经为此聊天创建了一个后端,有关此过程的描述的更多详细信息,您可以找到链接

首先,使用expo-cli创建一个新的expo项目,为此,我们在终端中执行命令:

expo init 

并按照向导的所有步骤创建一个空的应用程序。

收到创建的应用程序后,您需要添加将来将要使用的依赖项:

毛线添加apollo / react-hooks apollo缓存内存apollo客户端apollo-link-http apollo-link-ws apollo-utilities graphql graphql-tag native-base react-router-native subscriptions-transport-ws

完成后,下一步是连接和配置apollo客户端以使其与我们的后端一起使用。 为此,请将以下代码添加到App.js中。 我注意到这里我们将配置apollo以通过http和websocket协议连接到后端,并为apollo创建内存中缓存,并创建2条路由:一条用于登录表单,第二条用于聊天页面。

 get link() { const BACKEND_URL = Platform.OS === 'ios' ? 'localhost:3000' : '10.0.2.2:3000'; const httpLink = new HttpLink({ uri: `http://${BACKEND_URL}/graphql` }); const wsLink = new WebSocketLink({ uri: `ws://${BACKEND_URL}/graphql`, options: { reconnect: true } }); return split( // split based on operation type ({ query }) => { const definition = getMainDefinition(query); return ( definition.kind === 'OperationDefinition' && definition.operation === 'subscription' ); }, wsLink, httpLink, ); } async componentDidMount() { const cache = new InMemoryCache(); this.client = new ApolloClient({ link: this.link, cache }); …. } render() { return ( ... <ApolloProvider client={this.client}> <NativeRouter> <Route exact path="/" component={UsernameForm}/> <Route path="/chat" component={Chat}/> </NativeRouter> </ApolloProvider> ) } 

我不会详细描述表单的创建,我想您已经看过几次了,我只会说登录表单的代码可以在这里找到,为简单起见,我决定不添加授权和密码字段,但是,如果您愿意,您可以自己轻松地完成此操作。 。

我将关注一个有趣的点:

 const [ findOrCreateUser ] = useMutation(FIND_OR_CREATE_USER, { update(cache, { data: { findOrCreateUser: { id, username } } }) { cache.writeQuery({ query: GET_CURRENT_USER, data: { id, username }, }); } }); 

在这里,称为通过用户名添加/接收用户,以及将结果记录在缓存中以供其在应用程序的其他部分中进一步使用的变异。

实施登录表单后,下一项是聊天。

同样,我们将不讨论布局,可以在此处找到整个代码。

我们使用订阅功能来接收有关新聊天消息的通知,并在当前用户未创建消息时仅处理该线程,因为否则,该消息将已进入阿波罗缓存:

 useSubscription(MESSAGE_CREATED, { onSubscriptionData: ({ client, subscriptionData: { data: { messageCreated } } }) => { const { getLast100Messages } = client.readQuery({ query: GET_LAST_100_MESSAGES }); if (messageCreated.user.id !== id) { client.writeQuery({ query: GET_LAST_100_MESSAGES, data: { getLast100Messages: [ ...getLast100Messages, messageCreated ] } }); } } }); 

另一个有趣的地方是,当下载包含现有消息的聊天时,最旧的消息将显示在屏幕顶部,这对于用户来说是不寻常的,我们将使应用程序的行为更加自然,为此,我们添加了以下代码行:

 const scrollEl = useRef(null); … <Content ref={scrollEl} onContentSizeChange={() => { scrollEl.current.wrappedInstance.scrollToEnd({ animated: true }); }} > 

现在,当接收初始数据或添加新消息时,聊天将平滑滚动到最后一条消息。

剩下的代码没有意义,因为它类似于已经完成的工作,因此应用程序实现存储在存储库中

在实现了应用程序的所有功能之后,仅需测试应用程序的可操作性以及上一篇文章的后端。 在模拟器上启动的应用程序如下所示:

图片

Source: https://habr.com/ru/post/zh-CN471712/


All Articles