Writing clean code in PHP is very important. It makes your code more readable and easier to understand for others. We’ll outline 5 tips to enhance your code, so you can write cleaner and more understandable code.
Continue Reading “Clean code in PHP: 5 tips to help you!”Adding functionality to the app (Part 6)
In the previous part we’ve created a basic mobile app using React Native and the Expo framework. We’ve added login functionality and setup the router for our app. In this part we’re going add a registration screen and handle user activation using deeplinks.
The user registration screen
Let’s start by creating a user registration screen. This will be a very basic form for this series with just 4 input fields and a button. We’ll need the user’s first name, last name, email address and a password for the account.
Continue Reading “Adding functionality to the app (Part 6)”Setting up React Native (Part 5)
In the last part of this series we’ve finished our API for our stock portfolio. Today we’re going to start building our mobile app using React Native. We’ll start by setting up a new project using React Native, after which we’ll implement a basic login screen with login logic. This will cover the full spectrum, from building screens to calling our API for logging in.
Set up React Native
Install Expo
To make development with React Native a bit easier we’re going to use a framework called Expo. This framework consists of a set of tools to make developing, building and releasing React Native apps a lot easier.
Continue Reading “Setting up React Native (Part 5)”How to create a simple application using Symfony and React Native – Part 1
This is the first part of a new series I want to do. In this series I’ll be making a simple stock portfolio application using Symfony with API Platform. For the app we will use React Native. I’ll take you through the whole process, from setting up the basic Symfony application to the deployment of the API. You can follow along with me at Github.
Continue Reading “How to create a simple application using Symfony and React Native – Part 1”Integrate API’s in React and Redux with ease
When building a frontend for a web application in React and Redux it can be really tedious to integrate the backend API into it. You have to integrate a http library like axios, write the code to do the requests and much more. In your components you’ll call the requests and you have to keep track of the status of the requests. This creates a lot of boilerplate code, which can be really annoying. To combat this the folks at Redux created a nice tool called RTK Query.
What is RTK Query?
RTK Query is part of the Redux Toolkit. It’s a tool specifically created for fetching and caching data. It is built on top of other Redux Toolkit components like createAsyncThunk
and createSlice
. This is what makes it so puwerful.
The API it exposes is really easy to use and removes a lot of the boilerplate code that was necessary in the past. For example when you want to fetch the data of the current user you had to do it like this.
import axios from 'axios';
export default function UserMenu() {
const [user, setUser] = useState(undefined);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(undefined);
useEffect(() => {
if (!user) {
setIsLoading(true);
axios.get('/api/users/me')
.then(response => {
setUser(response.data);
setIsLoading(false);
})
.catch(error => {
setError(error);
setIsLoading(false);
});
}
});
return (
<div className="menu">
{isLoading && <Loader />}
{!isLoading && !error && <span className="username">{user.name}</span>}
</div>
)
}
Code language: JavaScript (javascript)
As you can see in the example you’ll have to manage the loading and error states by yourself. With RTK Query you don’t have to do this. Let me explain that with the same example as above, but this time with RTK Query.
import {useGetMeQuery} from './redux/api';
export default function UserMenu() {
const {data: user, isLoading, error} = useGetMeQuery();
return (
<div className="menu">
{isLoading && <Loader />}
{!isLoading && !error && <span className="username">{user.name}</span>}
</div>
)
}
Code language: JavaScript (javascript)
Now doesn’t this look a lot cleaner? You get the same functionality as the example above, but it much cleaner. And it gets even better.
Setup RTK Toolkit
It comes installed with the Redux Toolkit library. To install this toolkit simple install @reduxjs/toolkit
using your favorite package manager like yarn
or npm
. I’m going to assume you’ve setup your Redux Store already, so I’ll skip this part. Now we can implement our API using the createApi
function provided by the RTK Query tool. Let’s create our user API:
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react'
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: 'https://example.org/',
prepareHeaders: (headers, {getState}) => {
const token = getState().auth.token;
if (token) {
headers.set('Authorization', `Bearer ${token}`)
}
return headers;
}
}),
endpoints: build => ({
getMe: build.query({
query: () => (`/api/users/me`),
}),
createUser: build.mutation({
query: (request) => ({
url: '/api/users',
method: 'POST',
body: request,
}),
}),
}),
});
export const {useGetMeQuery, useCreateUserMutation} = api;
export default api;
Code language: JavaScript (javascript)
It doesn’t take much to define an API in RTK Query. We have to define the baseUrl
and for security we’ve added an extra header using prepareHeaders
which contains the bearer token. This callback has access to the state of your Redux store, so we can fetch the JWT Token from it.
The next part is the definition of the endpoints
. We’ve added support for the /api/users/me
endpoint which returns the user details of the owner of the JWT Token and a createUser
endpoint, which, like the name implies creates a new user.
Then we export the react hooks created by the createApi
function, which we can use in our application. And lastly we export the api
object.
To make this all work we need to register our API to the Redux Store, so let’s make this happen!
import {configureStore} from '@reduxjs/toolkit';
import api from './api';
import authReducer from './slices/auth';
// Define all reducers
const reducer = {
[api.reducerPath]: api.reducer,
auth: authReducer,
};
export const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware),
devTools: process.env.NODE_ENV !== 'production',
});
Code language: JavaScript (javascript)
First we need to add the reducer created by the createApi
function. This will make sure the data from the API calls will be stored in the Redux store. The next change we’ve made is to add the middleware the createApi
function created to the store using middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(api.middleware)
. This will make sure the advanced features of RTK Query like caching and such works correctly.
Code splitting
When you have an API with a lot of endpoints, your api.js
file will become pretty large and a nightmare to maintain. To remedy this RTK Query made it possible to inject endpoints in an existing API object. This makes the files a lot smaller and easier to maintain.
Let start with the base api.ts
file into which we can inject the extra endpoints from the other files.
import {createApi, fetchBaseQuery} from '@reduxjs/toolkit/query/react'
// Initialize an empty api service that we'll inject endpoints into later as needed
const api = createApi({
baseQuery: fetchBaseQuery({
baseUrl: 'https://example.org',
prepareHeaders: (headers, { getState }) => {
const token = getState().auth.token;
if (token) {
headers.set('Authorization', `Bearer ${token}`)
}
return headers;
}
}),
endpoints: () => ({}),
});
export default api;
Code language: JavaScript (javascript)
It looks pretty much the same as the other example, but we initialized the endpoints with an empty object. We’ll inject the endpoints later in the different files we’ll create.
import api from "./api";
const usersApi = api.injectEndpoints({
endpoints: build => ({
getMe: build.query({
query: () => (`/api/users/me`),
}),
createUser: build.mutation({
query: (request) => ({
url: '/api/users',
method: 'POST',
body: request,
}),
}),
}),
});
export const { useGetMeQuery, useCreateUserMutation } = usersApi;
export default usersApi;
Code language: JavaScript (javascript)
The object returned from the createApi
function has an injectEndpoints
method which we’ll use in our ‘API Extension points’. In the injectEndpoints
method we can simply add the endpoints we want.
Because we’ve already added the base API to our Redux store, there is no need to add extra reducers and middleware for our injected endpoints. When we want to load the current user we can simply use the useGetMeQuery
from the usersApi.ts
file above. This works the same as before.
Extra options
I haven’t even touched the surface of all the capabilities of the RTK Query tool. There are many more options for caching the data, refetching when needed and many more. I’ll write another article about this in the future. For now check out their official documentation for the information.