En aquest tema, aprendrem com gestionar l'estat de la nostra aplicació React i com integrar una API per obtenir i enviar dades. Aquest és un pas crucial per construir aplicacions React completes i funcionals.
Objectius del tema
- Comprendre com gestionar l'estat global de l'aplicació.
- Aprendre a utilitzar Redux per a la gestió de l'estat.
- Integrar una API RESTful amb React.
- Gestionar les sol·licituds HTTP i el cicle de vida de les dades.
- Configuració de Redux
Instal·lació de Redux i React-Redux
Primer, necessitem instal·lar les biblioteques necessàries per utilitzar Redux amb React.
Creació de l'estructura de Redux
1.1. Creació de l'Store
L'Store és on es guarda l'estat global de l'aplicació.
// src/store/index.js
import { createStore } from 'redux';
import rootReducer from '../reducers';
const store = createStore(rootReducer);
export default store;1.2. Creació del Reducer
El Reducer és una funció que especifica com canvia l'estat de l'aplicació en resposta a una acció.
// src/reducers/index.js
const initialState = {
data: [],
loading: false,
error: null,
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'FETCH_DATA_REQUEST':
return { ...state, loading: true, error: null };
case 'FETCH_DATA_SUCCESS':
return { ...state, loading: false, data: action.payload };
case 'FETCH_DATA_FAILURE':
return { ...state, loading: false, error: action.error };
default:
return state;
}
};
export default rootReducer;1.3. Proveïdor de Redux
Per connectar Redux amb React, utilitzem el proveïdor de React-Redux.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
- Integració de l'API
2.1. Creació de les Accions
Les accions són objectes que descriuen el tipus d'esdeveniment que ha ocorregut i les dades necessàries per actualitzar l'estat.
// src/actions/index.js
export const fetchDataRequest = () => ({
type: 'FETCH_DATA_REQUEST',
});
export const fetchDataSuccess = (data) => ({
type: 'FETCH_DATA_SUCCESS',
payload: data,
});
export const fetchDataFailure = (error) => ({
type: 'FETCH_DATA_FAILURE',
error,
});
export const fetchData = () => {
return (dispatch) => {
dispatch(fetchDataRequest());
fetch('https://api.example.com/data')
.then((response) => response.json())
.then((data) => dispatch(fetchDataSuccess(data)))
.catch((error) => dispatch(fetchDataFailure(error)));
};
};2.2. Utilització de Thunk Middleware
Per gestionar accions asíncrones, utilitzem redux-thunk.
// src/store/index.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;2.3. Connectar el Component a Redux
Finalment, connectem el component a Redux per accedir a l'estat i les accions.
// src/components/DataComponent.js
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from '../actions';
const DataComponent = () => {
const dispatch = useDispatch();
const { data, loading, error } = useSelector((state) => state);
useEffect(() => {
dispatch(fetchData());
}, [dispatch]);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h1>Data</h1>
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
};
export default DataComponent;Exercici Pràctic
Objectiu
Crear una aplicació que mostri una llista d'usuaris obtinguts d'una API i permeti afegir nous usuaris.
Passos
- Configura Redux: Crea l'Store, el Reducer i les Accions necessàries.
- Integra l'API: Utilitza
fetchper obtenir dades d'una API i actualitzar l'estat de l'aplicació. - Crea el Component: Crea un component que mostri la llista d'usuaris i un formulari per afegir nous usuaris.
Solució
// src/actions/index.js
export const addUser = (user) => ({
type: 'ADD_USER',
payload: user,
});
export const fetchUsers = () => {
return (dispatch) => {
dispatch(fetchDataRequest());
fetch('https://api.example.com/users')
.then((response) => response.json())
.then((data) => dispatch(fetchDataSuccess(data)))
.catch((error) => dispatch(fetchDataFailure(error)));
};
};
// src/reducers/index.js
const initialState = {
users: [],
loading: false,
error: null,
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case 'FETCH_DATA_REQUEST':
return { ...state, loading: true, error: null };
case 'FETCH_DATA_SUCCESS':
return { ...state, loading: false, users: action.payload };
case 'FETCH_DATA_FAILURE':
return { ...state, loading: false, error: action.error };
case 'ADD_USER':
return { ...state, users: [...state.users, action.payload] };
default:
return state;
}
};
export default rootReducer;
// src/components/UserComponent.js
import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUsers, addUser } from '../actions';
const UserComponent = () => {
const dispatch = useDispatch();
const { users, loading, error } = useSelector((state) => state);
const [name, setName] = useState('');
useEffect(() => {
dispatch(fetchUsers());
}, [dispatch]);
const handleAddUser = () => {
const newUser = { id: users.length + 1, name };
dispatch(addUser(newUser));
setName('');
};
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h1>Users</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Add a new user"
/>
<button onClick={handleAddUser}>Add User</button>
</div>
);
};
export default UserComponent;Resum
En aquest tema, hem après a gestionar l'estat global de l'aplicació amb Redux i a integrar una API per obtenir i enviar dades. Hem vist com configurar Redux, crear accions i reducers, i connectar els components de React a l'estat global. També hem practicat aquests conceptes amb un exercici pràctic. Ara estem preparats per avançar cap a temes més avançats en React.
Curs de React
Mòdul 1: Introducció a React
- Què és React?
- Configuració de l'entorn de desenvolupament
- Hola Món en React
- JSX: Extensió de la sintaxi de JavaScript
Mòdul 2: Components de React
- Comprendre els components
- Components funcionals vs components de classe
- Props: Passar dades als components
- State: Gestionar l'estat del component
Mòdul 3: Treballar amb esdeveniments
- Gestionar esdeveniments en React
- Renderització condicional
- Llistes i claus
- Formularis i components controlats
Mòdul 4: Conceptes avançats de components
- Elevar l'estat
- Composició vs herència
- Mètodes del cicle de vida de React
- Hooks: Introducció i ús bàsic
Mòdul 5: Hooks de React
Mòdul 6: Enrutament en React
Mòdul 7: Gestió de l'estat
- Introducció a la gestió de l'estat
- API de context
- Redux: Introducció i configuració
- Redux: Accions i reductors
- Redux: Connexió amb React
Mòdul 8: Optimització del rendiment
- Tècniques d'optimització del rendiment de React
- Memorització amb React.memo
- Hooks useMemo i useCallback
- Divisió de codi i càrrega mandrosa
Mòdul 9: Proves en React
- Introducció a les proves
- Proves unitàries amb Jest
- Proves de components amb React Testing Library
- Proves de punta a punta amb Cypress
Mòdul 10: Temes avançats
- Renderització del costat del servidor (SSR) amb Next.js
- Generació de llocs estàtics (SSG) amb Next.js
- TypeScript amb React
- React Native: Construir aplicacions mòbils
