React alapok

React alapjaiba bevezető leírás. Telepítés komponensek routing.

Telepítsünk egy react-os app-ot:
  1. # npx create-react-app projectnév

React fejlesztői környezet indítása, http://localhost:3000 itt fogjuk a böngészőben látni az eredményt:
  1. # cd projectnév // lépjünk be a mappájába előtte
  2. # npm start

A src mappában találjuk majd a compenenseinket és minden forrás fájlt.
Public mappában a képeket az indenx.html-t és egyéb mellékleteket találjuk / tároljuk.
Package.json-ban tudunk lehúzni újabb modulokat komponenseket, amelyek a node_modules mappába kerülnek és importálás után használhatóak lesznek a projektben.
A src mappában találjuk az index.js-t amiben inicializálódik az alkalmazás és az app.jsx-t "importálja be".
Az app.jsx lesz a szoftverünk kezdő komponense.

React-ban minden komponensekből épül fel. Célszerű mindent minnél kisebb komponensekre bontani. A komponenseknek a render részében a html elemek találhatóak, amik között js -el írhatunk feltételeket és ciklusokat stb. A komponensben a this.state nevű változóban levő értékek megváltozása indukálja egy komponens újra renderelődését. Ilyenkor a componentDidUpdate()-ban levő hívások lefutnak. A komponens létrehozásakor a componentDidMount() fut le. Amikor beágyazunk egy komponenst egy másikba, akkor adhatunk neki adattagokat és metódusokat. Amiket a belső komponensban a this.props-ban érünk el.

Egy átlagos komponens felépítése:
 
  1. import React, {Component} from 'react';
  2. import {Route, Switch} from 'react-router-dom';
  3. import PropTypes from 'prop-types';
  4.  
  5. class CitiesPage extends Component {
  6. state = {
  7. cities: this.getCities(),
  8. loading: false,
  9. errors: null,
  10. };
  11.  
  12. constructor(props) {
  13. super(props);
  14. }
  15.  
  16. async componentDidMount() {
  17. this.loadList();
  18. }
  19.  
  20. async componentDidUpdate(prevProps) {
  21.  
  22. }
  23.  
  24. loadList = async (params = this.props.params) => {
  25. this.props.showLoader();
  26. this.props.setCurrentParams(params);
  27. await this.props.getCitiesList(params);
  28. this.setState({loading: false});
  29. this.props.hideLoader();
  30. };
  31.  
  32. ...
  33.  
  34. render() {
  35. const {data: citiesList, loading} = this.props.citiesList;
  36. const {count} = this.props.citiesList;
  37.  
  38. return (
  39. <>
  40. ...
  41. <TableBody>
  42. {citiesList.map((city) => {
  43. return (
  44. <TableRow key={city.id}>
  45. <TableCell hasTooltip>{city.id}</TableCell>
  46. <TableCell hasTooltip>{city.name}</TableCell>
  47. <TableCell hasTooltip>{city.post_code}</TableCell>
  48. <TableCell className="col-2 icon-cell">
  49. <Access access={{module: 'core', section: 'controller_cities', type: 'modify'}}>
  50. <IconButton iconClass="edit" onClick={() => openEdit(city)}/>
  51. </Access>
  52. <Access access={{module: 'core', section: 'controller_cities', type: 'delete'}}>
  53. <IconButton iconClass="trash" onClick={() => openDeleteModal(city)}/>
  54. </Access>
  55. </TableCell>
  56. </TableRow>
  57. );
  58. })}
  59. </TableBody>
  60. ...
  61. <Modal
  62. className="confirm-modal"
  63. title={<Trans i18nKey="DICT.delete"/>}
  64. saveTitle={<Trans i18nKey="DICT.delete"/>}
  65. closeTitle={<Trans i18nKey="DICT.cancel"/>}
  66. saveAction={this.deleteCities}
  67. ref={this.deleteModal}>
  68. <Trans i18nKey="DICT.are_you_sure" values={{item: this.state.cities.name}}/>
  69. </Modal>
  70. </>
  71. }
  72. }
  73.  
  74. export default (CitiesPage);

A routing-ot a renderbe rakjuk és így néz ki pl:
 
  1. <Switch>
  2. <Route exact path="/"
  3. render={() => {
  4. return token ? <Redirect to={redirect} /> : <Redirect to="/login" />;
  5. }}
  6. />
  7. <Route path="/login"
  8. render={() => (token ? !isEmpty(profile) && <Redirect to={redirect} /> : <LoginPage />)}
  9. />
  10. }
  11. <Route path="/auth" render={() => <AuthPage />} />
  12. <Route path="/register" render={() => <RegisterPage />} />
  13. <Route path="/registeractivation" render={() => <RegisterPage />} />
  14. <Route exact path="*" render={() => (!token ? <Redirect to={loginRoute} /> : <Home />)} />
  15. <Route path="/404" component={NotFound} />
  16. <Redirect to="/404" />
  17. </Switch>
 
Egy service fájl példa:
  1. import qs from 'query-string';
  2.  
  3. import request from 'libs/request';
  4. import { Methods } from 'libs/http';
  5.  
  6. const BASE_URL = '/city';
  7.  
  8. export const getCity = async (id) => {
  9. return await request({
  10. method: Methods.GET,
  11. resource: `${BASE_URL}/show/${id}`,
  12. });
  13. };
  14.  
  15. export const createCity = async (data) => {
  16. return await request({
  17. method: Methods.POST,
  18. resource: `${BASE_URL}/store`,
  19.  
  20. data,
  21. });
  22. };
  23.  
  24. export const editCity = async (data, id) => {
  25. return await request({
  26. method: Methods.PUT,
  27. resource: `${BASE_URL}/update/${id}`,
  28.  
  29. data,
  30. });
  31. };
  32.  
  33. export const deleteCity = async (id) => {
  34. return await request({
  35. method: Methods.DELETE,
  36. resource: `${BASE_URL}/destroy/${id}`,
  37. });
  38. };
  39.  
  40. export const getCityList = async (params) => {
  41. return await request({
  42. method: Methods.GET,
  43. resource: `${BASE_URL}?${qs.stringify(params, {encode: false, arrayFormat: 'bracket'})}`,
  44. });
  45. };
 
Meghívni egy komponensben egy service funkciót:
 
  1. import * as EventsService from 'modules/core/services/events';
  2. ...
  3. load = async (params = this.props.filterParams) => {
  4. const newParams = merge({}, params);
  5. delete newParams.page;
  6. const cityList = await CityService.getCityList(newParams);
  7. return cityList.data || {};
  8. };

Projektet a következő paranccsal lehet buildelni:
 
  1. # npm run build

Keletkezik egy build mappa, amit felmásolhatunk egy szerverre.

Olvasnivaló
https://reactjs.org/
https://reactrouter.com/web/guides/quick-start
https://reactjs.org/docs/components-and-props.html
https://hu.reactjs.org/docs/react-component.html

 
2020.04.04.