Debo decir de inmediato que el sitio funcionará más rápido si reemplaza Bootstrap con CSS y JS puros. Este artículo trata sobre cómo comenzar a desarrollar rápidamente aplicaciones web hermosas, y la optimización ya es un tema separado que va más allá del alcance de este artículo.
Primero debe comprender al menos un poco de HTML, CSS, JavaScript, XML, DOM, OOP y poder trabajar en la terminal (línea de comando).
¿Dónde conseguir materiales para estudiar?Para aprender HTML y CSS, recomiendo
htmlbook.ruPara aprender JavaScript, recomiendo
learn.javascript.ruPara aprender XML recomiendo
msiter.ru/tutorials/uchebnik-xml-dlya-nachinayushchihPuede leer sobre el DOM en la lección de JavaScript
learn.javascript.ru/dom-nodesPara estudiar OOP, recomiendo el video curso
proglib.io/p/oop-videocoursePara explorar la línea de comandos de Windows, recomiendo
cmd.readthedocs.io/cmd.htmlPara estudiar el terminal en una Mac, recomiendo
ixrevo.me/mac-os-x-terminalSi está trabajando en Linux, entonces
bash y análogos saben que, en última instancia, el
hombre o la
ayuda lo
ayudarán .
Para aprender React, utilizo
learn-reactjs.ru (que es una traducción de la documentación oficial de React:
reactjs.org ).
Para estudiar Bootstrap, uso
bootstrap-4.ru (que es una traducción de la documentación oficial de Bootstrap:
getbootstrap.com ).
Para hacer amigos Reaccionar y Bootstrap encontré un excelente artículo
webformyself.com/kak-ispolzovat-bootstrap-s-react En este artículo, exprimiré el mínimo necesario para el trabajo y haré un temporizador de este tipo:

Instalación
Primero necesitamos un administrador de paquetes. Elegí
npm , y está en
Node.jsEn primer lugar, instale
Node.js en su sistema operativo desde el sitio oficial:
nodejs.org/en/download . Puede averiguar la instalación, por lo que no describiré el proceso de instalación. Solo noto que instalar bajo Ubuntu es simple:
sudo apt update sudo apt install nodejs sudo apt install npm
A través del terminal, verificamos que Node.js y npm se hayan instalado correctamente:
nodejs -v npm -v
Si hay errores durante la salida, significa que algo salió mal y necesita comprenderlo, y es posible reinstalarlos. Si vc se muestra con números y puntos, entonces todo está bien.
Instale Create-react-app para que pueda crear rápidamente marcos de aplicaciones:
npm install -g create-react-app
A continuación, creamos el marco de la aplicación en React. Pongamos nombre a nuestra aplicación
nueva aplicación . Si desea crear una aplicación para una carpeta diferente de la carpeta del usuario, primero vaya al terminal a través del terminal utilizando el
comando cd . Entonces, en la terminal, solo ingrese 3 comandos:
create-react-app new-app cd new-app npm start
Creamos la
aplicación de nueva aplicación. Vaya a la carpeta de la
nueva aplicación . Lanzamos la aplicación. Después de estas líneas, el navegador con la aplicación React debe comenzar en la dirección
http: // localhost: 3000
El terminal debe permanecer abierto, sin él la página de la aplicación no se abrirá. Si de repente cerraste, no importa. Es suficiente usar el
comando cd para ir a la carpeta de la aplicación e iniciarlo con el comando
npm startAhora instale bootstrap
npm install bootstrap
También se recomienda instalar las dependencias jquery y popper.js en él, pero solo son necesarios para la parte Bootstrap JS. Lo intenté sin ellos: la parte CSS de Bootstrap funciona bien, por lo que las siguientes líneas en el terminal son opcionales:
npm install jquery popper.js
A continuación, debe realizar cambios en los archivos de la aplicación, para esto, vaya a la carpeta de la nueva aplicación, donde se encuentra la aplicación, agregue la línea al archivo
src / index.js , debería ser el primero:
import 'bootstrap/dist/css/bootstrap.min.css';
Si usa jQuery, popper.js o la parte Bootstrap JS (ventanas modales, animaciones, etc.), deberá agregar 3 líneas más debajo de la primera línea:
import $ from 'jquery'; import Popper from 'popper.js'; import 'bootstrap/dist/js/bootstrap.bundle.min';
Ahora queda por ejecutar el proyecto:
npm start
Y nuevamente, el navegador se abre en
http: // localhost: 3000 ya con la aplicación habilitada usando Bootstrap:

También para depurar React, puede instalar la extensión "
React Developer Tools " para el navegador. Los enlaces actuales a la extensión para
Chrome y
Firefox y otros casos de uso se enumeran en el repositorio oficial
github.com/facebook/react-devtoolsLa instalación y la configuración inicial ahora están completas.
JSX, componentes y propiedades
Veamos qué
crear-reaccionar-aplicación generó para nosotros: los archivos de origen están en el directorio src. Primero, veamos el archivo
index.js : hay varias líneas de importación. De las líneas está claro lo que están haciendo, así que no voy a comentar.
La línea más importante en este archivo:
ReactDOM.render(<App />, document.getElementById('root'));
Dibuja la página de la aplicación. Hay un elemento
<div> con id = root en el archivo HTML de origen. Este
<div> muestra el componente de la
aplicación , que es dibujado por la función de representación de la clase
ReactDOM . En este caso, el componente se dibuja en una forma similar a XML, que se llama JSX (sobre el cual más adelante).
Ahora pasemos al archivo
App.js , donde se encuentra la implementación de la clase App, que hereda de la clase
React.Component .
class App extends React.Component { <b>render()</b>, JSX: <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>
JSX es muy similar a HTML, pero hay inserciones de código JS en llaves {}. Y debe haber un elemento raíz, en este caso <div>.
Para comprender mejor, borraremos todo el código del método
render () y escribiremos el componente más simple:
class App extends React.Component { render() { return <h1>, {this.props.name}!</h1>; } }
Ahora, volvamos al archivo index.js y arreglemoslo.
ReactDOM.render(<App name="" />, document.getElementById('root'));
Después de guardar los archivos, la página se actualizará en el navegador. Y ahora lo entenderemos.
Conceptualmente, los componentes son similares a las funciones de JavaScript. Toman datos arbitrarios (llamados accesorios) y devuelven elementos React que describen lo que debería aparecer en la pantalla. Los componentes le permiten dividir la IU en partes independientes reutilizables y trabajar con cada una de ellas por separado.
Cuando React ve que un elemento es un componente personalizado, pasa todos los atributos JSX a ese componente como un solo objeto. Tal objeto se llama accesorios.
En el ejemplo, el parámetro de
nombre se pasa al componente como un atributo de la
etiqueta <App> con el valor "
Mundo ". Además, en el método
render () de la clase
App , como resultado de una función dentro de JSX, que en realidad es una plantilla HTML, las llaves
{} indican
esto : la clase actual, los
accesorios , el objeto de usuario, el
nombre , el nombre del parámetro del objeto.
Constructor, ciclo de vida y cambio de estado
Además de los parámetros almacenados en los
accesorios, puede almacenar el estado del objeto en
estado .
Hagamos un temporizador. No se necesitan parámetros para el temporizador, así que eliminemos los parámetros en
index.js :
ReactDOM.render(<App/>, document.getElementById('root'));
Y ahora en el archivo
App.js reemplazamos todo el texto entre
importación y
exportación :
const INTERVAL = 100; class App extends Component { constructor(props) { super(props); this.state = {value: 0}; } increment(){ this.setState({value: this.state.value + 1}); } componentDidMount() { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); } componentWillUnmount() { clearInterval(this.timerID); } render() { const value = this.state.value return ( <div> <p>:</p> <p> <span>{Math.floor(value/INTERVAL/60/60)} : </span> <span>{Math.floor(value/INTERVAL/60) % 60} : </span> <span>{Math.floor(value/INTERVAL) % 60} . </span> <span>{value % INTERVAL}</span> </p> </div> ); } }
Después de insertar y guardar este código, aparecerá un temporizador en la página y se iniciará automáticamente.
Analicemos este código. Antes de la clase, se anunció una constante, gracias a la cual puede ajustar la frecuencia de actualización del temporizador.
A continuación, dentro de la clase hay un constructor obligatorio de la clase, al que se pasan los accesorios. A continuación, el procesamiento estándar del constructor de la clase padre
super (props) y la determinación del estado de
valor a través de
esto es el objeto actual. Este es el único lugar donde puede establecer directamente el estado. En otros lugares, solo está disponible la lectura, o establecer el estado con el método
setState () especial, que se utiliza en el siguiente método
increment () para aumentar el estado del
valor en uno.
En aplicaciones con muchos componentes, es muy importante liberar recursos ocupados por componentes cuando se destruyen. Necesitamos establecer un temporizador cada vez que se dibuja el DOM por primera vez. En React, esto se llama "montar / instalar". También necesitamos borrar este temporizador cada vez que se elimina el DOM creado por el componente. En React, esto se llama "desmontaje / desmontaje".
Para esto, se utilizan los métodos
componentDidMount () y
componentWillUnmount () . En la documentación, estos métodos se denominan "
ganchos de ciclo de vida ". Por simplicidad, los llamaremos métodos de ciclo de vida. El método
componentDidMount () se activa después de que el componente se haya procesado en el DOM. Este es un buen lugar para configurar un temporizador. Borraremos el temporizador en el método
componentWillUnmount () del ciclo de vida.
Observe cómo en
componentDidMount () almacenamos la ID del temporizador directamente en
esto usando la función de flecha. Si bien this.props se instala de forma independiente por React y
this.state tiene un significado específico, puede agregar libremente campos adicionales a la clase manualmente si necesita almacenar algo que no se utiliza para la salida visual. Si no está usando algo en
render () , no debería estar en estado
estado .
Además, durante la ejecución de
render () , el estado del valor se fija en el valor constante local. Y luego, usando la función matemática
floor () , que redondea el número hacia abajo, dividiendo (
/ ) y obteniendo el resto de la división (
% ) obtenemos las partes del temporizador, que luego se muestran en la misma línea después de la palabra Timer. Puedes ver los resultados de nuestro trabajo.
Apariencia con Bootstrap
No es conveniente que el temporizador funcione de inmediato cuando se actualiza la página. Me gustaría que se inicie y se detenga cuando haga clic en los botones correspondientes. Y me gustaría que fuera en el centro y grande.
Comencemos con el diseño. Para hacer esto, agregue las siguientes líneas al archivo
App.css :
.container-fluid { display: flex; flex-direction: column; }
Gracias al
contenedor de goma adaptable
contenedor de fluido en Bootstrap, que ayuda a crear un diseño totalmente flexible para una página o bloque. Este contenedor es 100% ancho. Hagamos un contenedor
flexible , con la dirección de alinear los elementos verticalmente, de modo que ocupe todo el espacio y pueda alinearse en el centro.
Ahora finalicemos el método
render () en
App.js para aplicar estilos Bootstrap y agregar un par de botones. Para hacer esto, reemplace el valor devuelto por el método con lo siguiente:
<div class="container-fluid align-items-center"> <h1 class="display-1"></h1> <h1 class="display-1"> <span><kbd>{Math.floor(value/INTERVAL/60/60)}</kbd> : </span> <span><kbd>{Math.floor(value/INTERVAL/60) % 60}</kbd> : </span> <span><kbd>{Math.floor(value/INTERVAL) % 60}</kbd> . </span> <span><kbd>{value % INTERVAL < 10 ? '0' : ''}{value % INTERVAL}</kbd></span> </h1> <div> <button class="display-4"></button> <button class="display-4"></button> </div> </div>
En la primera línea, se agregaron 2 clases Bootstrap a la raíz
<div> :
container-fluid (que escribí anteriormente) y
align-items-center , que solo alinea los elementos del contenedor en el centro.
A continuación, dos
<div> con la clase
display-1 : esta clase es solo para mostrar texto grande.
A continuación, se agregó una nueva etiqueta
<kbd> a los números, que generalmente se usa para resaltar las teclas que deben presionarse. En este caso, es ideal para contrastar los números mostrados.
La expresión condicional se agrega en el último dígito, que muestra parte de un segundo, lo que permite que los dígitos de un solo dígito (<10) se emitan al principio 0 y no se emitan para números de dos dígitos. Esto es necesario para que los números no se contraigan cada segundo. Para hacer esto, use el operador de JavaScript ternario:
¿condición? verdadero: falsoLuego, en un
<div> separado
, coloqué 2 botones con la clase
Display-4 : esta clase se seleccionó como el tamaño más adecuado para que los botones se correspondan con el tamaño del temporizador. Inserté un caracter entre los botones
- Espacio inextricable para que los botones no se fusionen.
Puede comenzar, pero los botones aún no funcionan. Enseñemos a los botones a trabajar.
Manejo de eventos
Primero, agregue la llamada a las funciones correspondientes en el código de salida del botón:
<button class="display-4" onClick={this.stopTimer}></button> <button class="display-4" onClick={this.resetTimer}></button>
Tenga en cuenta que en React, el
controlador de eventos
onClick , no
onclick , como en JavaScript, y la función llamada se indica entre llaves sin paréntesis e indica el objeto desde el que se llama el método, en este caso
esto .
Ahora definimos los métodos especificados
stopTimer () y
resetTimer () :
stopTimer(){ clearInterval(this.timerID); } resetTimer(){ this.setState({value: 0}); }
Pero esto aún no es suficiente, y si lo deja así, cuando presione el botón aparecerá un error, esto al llamar a la función será
indefinido . Esto se debe a que en JavaScript, los métodos de clase no están vinculados de forma predeterminada. Por lo general, si hace referencia a un método sin () después de él, por ejemplo,
onClick = {this.resetTimer} , debe vincular este método.
Vincula los métodos en el constructor de la clase agregando 2 líneas:
this.stopTimer = this.stopTimer.bind(this); this.resetTimer = this.resetTimer.bind(this);
Genial, funcionó! Pero solo el botón de detener se puede usar solo 1 vez, y después de eso los botones dejan de funcionar. Y esto es lógico, porque al llamar a
stopTimer () deshabilitamos la llamada a la función regular llamando a
clearInterval () .
Los comentarios sugirieron usar funciones de flecha. Intentado funciona. Por lo tanto, no puede agregar 2 líneas al constructor, sino reemplazar las funciones mismas con las siguientes funciones de flecha:
stopTimer = () => { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); } resetTimer = () => { this.setState({value: 0}); }
Para resolver esto, haremos que el botón "Parar" también funcione como "Ejecutar".
Primero, agregue el estado booleano
detenido al constructor para comprender en qué modo funciona el botón:
this.state = {value: 0, stopped: false};
Ahora reemplace completamente el contenido del método
stopTimer () :
this.setState({stopped: !this.state.stopped}); if(this.state.stopped){ clearInterval(this.timerID); } else { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); };
Al comienzo del método, cambie el estado
detenido al opuesto mediante
setState () .
Además, si el temporizador debe detenerse (es decir,
parado = verdadero ), entonces deshabilitamos la llamada de función regular a través de
clearInterval () , y si el temporizador debe iniciarse (es decir,
parado = falso ), entonces inicie la llamada de función regular de la misma manera que
componentDidMount () .
También debe corregir el método
increment () para que se detenga cuando se
detenga = verdadero :
increment(){ if(!this.state.stopped) (this.setState({value: this.state.value + 1})); }
Y finalmente, cambiamos el nombre del botón según el estado detenido, insertando lo siguiente en lugar de "Stop":
{this.state.stopped?'':''}
Ahora tenemos un temporizador hermoso y conveniente.
En lugar de una conclusión o una cereza en un pastel
Finalmente, me gustaría cambiar el título estándar y el ícono de la ventana al nuestro.
Puede cambiar el título configurando
document.title en el método
componentDidMount () , pero seguiremos adelante y haremos que el tiempo de visualización del título de la página sea exacto en segundos, para esto agregaremos la configuración
document.title al método especial
componentDidUpdate () :
componentDidUpdate(){ const value = this.state.value; if (this.state.stopped) document.title = ""; else document.title = ": "+Math.floor(value/INTERVAL/60/60)+":" +Math.floor(value/INTERVAL/60) % 60+":"+Math.floor(value/INTERVAL) % 60; }
Ahora el temporizador se repite hasta segundos en el título de la página, y cuando se detiene el temporizador, solo se muestra la palabra Temporizador.
El ícono es simple. Es suficiente preparar una imagen en formato
jpg ,
bmp ,
gif ,
png , colocarla en la carpeta
pública (y no en el
src , en el que trabajamos principalmente), nombrar, por ejemplo,
favicon.png y cambiar la línea en el archivo
public \ index.html :
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
por línea:
<link rel="shortcut icon" type="image/png" href="/favicon.png"/>
Por hoy, eso es todo lo que quería contar. En el próximo artículo hablaré más sobre Bootstrap, que en este artículo solo ha tocado un poco. Además de Bootstrap, todavía hay temas importantes: listas, tablas, formularios y pensamiento al estilo React.
Finalmente, el repositorio en BitBucket, que tiene todo el código para este artículo