ReactJS en 20 pasos
React es una biblioteca JavaScript de código abierto diseñada para crear interfaces de usuario con el objetivo de facilitar el desarrollo de aplicaciones de una sola página (SPA). En esta guía repasamos en 20 pasos lo esencial: crear un proyecto, los hooks más usados, formularios, peticiones HTTP, estilos y rutas.
1. Instalación
npm install -g create-react-app
2. Crear un proyecto
create-react-app nombre_proyecto
3. Ejecutar el proyecto
cd nombre_proyecto
npm start
4. Compilar el proyecto
npm run build
5. Ejecutar el proyecto en modo release
npm run build
serve -s build
6. useState
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
7. useEffect
import React, { useState, useEffect } from 'react';
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
8. useContext
import React, { useState, useEffect, useContext } from 'react';
const CountContext = React.createContext();
function Counter() {
const count = useContext(CountContext);
return <h1>{count}</h1>;
}
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<CountContext.Provider value={count}>
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
<Counter />
</div>
</CountContext.Provider>
);
}
9. useReducer
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, {count: 0});
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
function App() {
return <Counter />;
}
10. useRef
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
function App() {
return <TextInputWithFocusButton />;
}
11. useMemo
import React, { useMemo } from 'react';
function App() {
const expensiveResult = useMemo(() => {
return computeExpensiveValue(a, b);
}, [a, b]);
return <ChildComponent>{expensiveResult}</ChildComponent>;
}
12. useCallback
import React, { useCallback } from 'react';
function App() {
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
return <ChildComponent onClick={memoizedCallback} />;
}
13. Map
import React from 'react';
function App() {
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
14. Layout
import React from 'react';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
15. Estilos
import React from 'react';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
16. Formularios
import React, { useState } from 'react';
function App() {
const [value, setValue] = useState('Controlled');
const handleChange = (event) => {
setValue(event.target.value);
};
const handleSubmit = (event) => {
alert('A name was submitted: ' + value);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={value} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
17. Formik + Yup
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';
const SignupSchema = Yup.object().shape({
firstName: Yup.string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required('Required'),
lastName: Yup.string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required('Required'),
email: Yup.string().email('Invalid email').required('Required'),
});
function App() {
return (
<div>
<h1>Anywhere in your app!</h1>
<Formik
initialValues={{
firstName: '',
lastName: '',
email: '',
}}
validationSchema={SignupSchema}
onSubmit={values => {
// same shape as initial values
console.log(values);
}}
>
{({ errors, touched }) => (
<Form>
<Field name="firstName" />
{errors.firstName && touched.firstName ? (
<div>{errors.firstName}</div>
) : null}
<Field name="lastName" />
{errors.lastName && touched.lastName ? (
<div>{errors.lastName}</div>
) : null}
<Field name="email" type="email" />
{errors.email && touched.email ? <div>{errors.email}</div> : null}
<button type="submit">Submit</button>
</Form>
)}
</Formik>
</div>
);
}
18. Axios
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [data, setData] = useState({ hits: [] });
useEffect(() => {
const fetchData = async () => {
const result = await axios(
'https://hn.algolia.com/api/v1/search?query=redux',
);
setData(result.data);
};
fetchData();
}, []);
return (
<ul>
{data.hits.map(item => (
<li key={item.objectID}>
<a href={item.url}>{
item.title
}</a>
</li>
))}
</ul>
);
}
19. Styled Components
import React from 'react';
import styled from 'styled-components';
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
function App() {
return (
<Wrapper>
<Title>
Hello World, this is my first styled component!
</Title>
</Wrapper>
);
}
20. React Router
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Users() {
return <h2>Users</h2>;
}
Nota
Create React App ya no es la opción recomendada para empezar proyectos nuevos; hoy la documentación oficial de React sugiere frameworks como Next.js o herramientas como Vite (npm create vite@latest). Además, el ejemplo de React Router usa la sintaxis de la versión 5 (Switch); a partir de la versión 6 se usa Routes y la propiedad element.