github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/example/chat/src/Room.js (about) 1 import React, { useState, useEffect, useRef } from 'react'; 2 import gql from 'graphql-tag'; 3 import { useQuery, useMutation } from '@apollo/react-hooks'; 4 import { Chat, ChatContainer, Message, MessageReceived } from './components/room'; 5 6 export const Room = ({ channel, name }) => { 7 const messagesEndRef = useRef(null) 8 const [ text, setText ] = useState(''); 9 10 const [ addMessage ] = useMutation(MUTATION, { 11 onCompleted: () => { 12 setText(''); 13 } 14 }); 15 16 const { loading, error, data, subscribeToMore } = useQuery(QUERY, { 17 variables: { 18 channel 19 }, 20 }); 21 22 // subscribe to more messages 23 useEffect(() => { 24 const subscription = subscribeToMore({ 25 document: SUBSCRIPTION, 26 variables: { 27 channel, 28 }, 29 updateQuery: (prev, { subscriptionData }) => { 30 31 if (!subscriptionData.data) { 32 return prev; 33 } 34 const newMessage = subscriptionData.data.messageAdded; 35 36 if (prev.room.messages.find((msg) => msg.id === newMessage.id)) { 37 return prev 38 } 39 40 return Object.assign({}, prev, { 41 room: Object.assign({}, prev.room, { 42 messages: [...prev.room.messages, newMessage], 43 }) 44 }); 45 }, 46 }); 47 48 49 return () => subscription(); 50 51 }, [subscribeToMore, channel]); 52 53 // auto scroll down 54 useEffect(() => { 55 messagesEndRef && messagesEndRef.current && messagesEndRef.current.scrollIntoView({ behavior: 'smooth' }) 56 }, [messagesEndRef, data]); 57 58 if (loading) { 59 return <div>loading</div> 60 } 61 62 if (error) { 63 return <div>error</div> 64 } 65 66 return (<> 67 <Chat> 68 <ChatContainer> 69 {data.room.messages.map((msg) => 70 msg.createdBy === name ? <Message key={msg.id}> 71 {msg.text} 72 </Message> : <MessageReceived key={msg.id}> 73 <span>{msg.createdBy}</span> 74 {msg.text} 75 </MessageReceived> 76 )} 77 </ChatContainer> 78 <div ref={messagesEndRef} /> 79 </Chat> 80 81 <input value={text} onChange={(e) => setText(e.target.value)} /> 82 83 <p> 84 <button 85 onClick={() => addMessage({ 86 variables: { 87 text: text, 88 channel: channel, 89 name: name, 90 } 91 }) 92 } > 93 send 94 </button> 95 </p> 96 </>); 97 98 } 99 100 const SUBSCRIPTION = gql` 101 subscription MoreMessages($channel: String!) { 102 messageAdded(roomName:$channel) { 103 id 104 text 105 createdBy 106 } 107 } 108 `; 109 110 const QUERY = gql` 111 query Room($channel: String!) { 112 room(name: $channel) { 113 messages { id text createdBy } 114 } 115 } 116 `; 117 118 const MUTATION = gql` 119 mutation sendMessage($text: String!, $channel: String!, $name: String!) { 120 post(text:$text, roomName:$channel, username:$name) { id } 121 } 122 `;