[ PART 14 ] Create a Twitter clone with GraphQL, Typescript, and React ( starting the Frontend )
Table of contents
Hi everyone ;).
As a reminder, I'm doing this Tweeter challenge
A little bit of Frontend
For the Frontend part, I will use React + Tailwindcss + Typescript. I just found a template so let's try it. If I can win some time avoiding configuring everything... I'll take it ^^. For the design, every challenge on devChallenges.io provides a Figma file so I don't have to start the design from scratch. You can thanks {% user nghiemthu %} :D
npx create-react-app challenge_twitter_front --template tailwindcss-typescript
yarn start
Everything seems to work. Let's add more libraries that I will need.
yarn add @apollo/client graphql recoil react-hook-form @hookform/resolvers yup react-router-dom date-fns react-icons
@apollo/client and graphql: for our queries/mutation & graphql related stuff
recoil: for our global state management
react-hook-form @hookform/resolvers yup: for our form validation
react-router-dom: The router
date-fns: we'll have some date to format
react-icons: To have some icons to play with ;)
To start, let's just add the Router with some pages:
src/App.tsx
import React from 'react'
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
import Home from './pages/Home'
import Login from './pages/Login'
import Register from './pages/Register'
function App() {
return (
<Router>
<Switch>
<Route exact path="/login">
<Login />
</Route>
<Route exact path="/register">
<Register />
</Route>
<Route exact path="/">
<Home />
</Route>
</Switch>
</Router>
)
}
export default App
And as an example, here is my Register page:
src/pages/Register.tsx
import React from 'react'
const Register = () => {
return <div>Register</div>
}
export default Register
Register a user
We will start with the authentication. We will use react-hooker-form with yup for the validation. But before working on the Register page, let's create our apolloClient.
src/client/index.ts
import { ApolloClient, InMemoryCache } from '@apollo/client'
const client = new ApolloClient({
uri: process.env.REACT_APP_BACKEND_URL || 'http://localhost:4000',
cache: new InMemoryCache(),
})
export default client
For now, I just follow the documentation ;). To have access to some hooks provided by the apolloClient, we will wrap our App with the ApolloProvider
src/index.tsx
import { ApolloProvider } from '@apollo/client'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import client from './client'
import './styles/index.css'
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
)
Just for the sake of testing if everything works as expected I will play on my Register page ;).
src/pages/Register.ts
import { gql, useMutation } from '@apollo/client'
import React from 'react'
const REGISTER = gql`
mutation($input: RegisterPayload!) {
register(input: $input) {
token
user {
id
username
display_name
email
created_at
updated_at
}
}
}
`
const Register = () => {
const [register, { loading, data, error }] = useMutation(REGISTER)
return (
<div>
<button
onClick={() => {
register({
variables: {
input: {
username: 'new',
email: 'new@test.fr',
display_name: 'New',
password: 'password',
},
},
})
}}
>
Register
</button>
{loading && <div>Loading...</div>}
{data && <div>{data.register.user.username}</div>}
</div>
)
}
export default Register
Don't forget to start the server and let's give it a try ;).
Nice ;). The client seems to work as expected.
I will stop here for now and I will start to work on the user's registration in the next part ;).
Ciao & Take care ;).