React alapok

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

Telepítsünk egy react-os app-ot:
# 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:
# cd projectnév  // lépjünk be a mappájába előtte
# 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:
 
import React, {Component} from 'react';
import {Route, Switch} from 'react-router-dom';
import PropTypes from 'prop-types';

class CitiesPage extends Component {
   state = {
        cities: this.getCities(),
        loading: false,
        errors: null,
    };

    constructor(props) {
        super(props);
    }

    async componentDidMount() {
         this.loadList();
    }

    async componentDidUpdate(prevProps) {

    }

    loadList = async (params = this.props.params) => {
        this.props.showLoader();
        this.props.setCurrentParams(params);
        await this.props.getCitiesList(params);
        this.setState({loading: false});
        this.props.hideLoader();
    };

    ...

    render() {
        const {data: citiesList, loading} = this.props.citiesList;
        const {count} = this.props.citiesList;

        return (
             <>
                   ...
                <TableBody>
                    {citiesList.map((city) => {
                        return (
                            <TableRow key={city.id}>
                                <TableCell hasTooltip>{city.id}</TableCell>
                                <TableCell hasTooltip>{city.name}</TableCell>
                                <TableCell hasTooltip>{city.post_code}</TableCell>
                                <TableCell className="col-2 icon-cell">
                                    <Access access={{module: 'core', section: 'controller_cities', type: 'modify'}}>
                                        <IconButton iconClass="edit" onClick={() => openEdit(city)}/>
                                    </Access>
                                    <Access access={{module: 'core', section: 'controller_cities', type: 'delete'}}>
                                        <IconButton iconClass="trash" onClick={() => openDeleteModal(city)}/>
                                    </Access>
                                </TableCell>
                            </TableRow>
                        );
                    })}
                </TableBody>
                       ...
                  <Modal
                        className="confirm-modal"
                        title={<Trans i18nKey="DICT.delete"/>}
                        saveTitle={<Trans i18nKey="DICT.delete"/>}
                        closeTitle={<Trans i18nKey="DICT.cancel"/>}
                        saveAction={this.deleteCities}
                        ref={this.deleteModal}>
                        <Trans i18nKey="DICT.are_you_sure" values={{item: this.state.cities.name}}/>
                    </Modal>
              </>
     }
}

export default (CitiesPage);

A routing-ot a renderbe rakjuk és így néz ki pl:
 
<Switch>
        <Route exact path="/"
          render={() => {
            return token ? <Redirect to={redirect} /> : <Redirect to="/login" />;
          }}
        />
        <Route path="/login"
          render={() => (token ? !isEmpty(profile) && <Redirect to={redirect} /> : <LoginPage />)}
        />
        }
        <Route path="/auth" render={() => <AuthPage />} />
        <Route path="/register" render={() => <RegisterPage />} />
        <Route path="/registeractivation" render={() => <RegisterPage />} />
        <Route exact path="*" render={() => (!token ? <Redirect to={loginRoute} /> : <Home />)} />
        <Route path="/404" component={NotFound} />
        <Redirect to="/404" />
</Switch>
 
Egy service fájl példa:
import qs from 'query-string';

import request from 'libs/request';
import { Methods } from 'libs/http';

const BASE_URL = '/city';

export const getCity = async (id) => {
  return await request({
    method: Methods.GET,
    resource: `${BASE_URL}/show/${id}`,
  });
};

export const createCity = async (data) => {
  return await request({
    method: Methods.POST,
    resource: `${BASE_URL}/store`,

    data,
  });
};

export const editCity = async (data, id) => {
  return await request({
    method: Methods.PUT,
    resource: `${BASE_URL}/update/${id}`,

    data,
  });
};

export const deleteCity = async (id) => {
  return await request({
    method: Methods.DELETE,
    resource: `${BASE_URL}/destroy/${id}`,
  });
};

export const getCityList = async (params) => {
  return await request({
    method: Methods.GET,
    resource: `${BASE_URL}?${qs.stringify(params, {encode: false, arrayFormat: 'bracket'})}`,
  });
};
 
Meghívni egy komponensben egy service funkciót:
 
import * as EventsService from 'modules/core/services/events';
...
  load = async (params = this.props.filterParams) => {
    const newParams = merge({}, params);
    delete newParams.page;
    const cityList = await CityService.getCityList(newParams);
    return cityList.data || {};
  };

Projektet a következő paranccsal lehet buildelni:
 
# 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.