Varias formas de optimizar una aplicación React-Redux

Parecería por qué hablar de Redux en 2020. Después de todo, hay muchas alternativas excelentes en el campo de los administradores estatales ( por ejemplo ). Después de todo, hay una docena de razones para no gustarle Redux, sobre las cuales se han escrito muchos artículos y se han hecho muchos informes. Sin embargo, no se le puede quitar algo: puede escribir en él un sitio web grande, funcional, compatible y rápido . A continuación hablaré sobre las técnicas que ayudan a hacer esto usando react-redux. ¿Interesante? Bienvenido a cat.


Optimizando la aplicación redux


Descargo de responsabilidad Para una persona que ha leído cuidadosamente la documentación, no se producirá un desglose de la cubierta. Tu capitán


Personalmente, amo a Redux. Por simplicidad y minimalismo. La biblioteca no hace magia. Donde no hay magia, no hay forma de romper algo accidentalmente, sin saber qué fue lo que rompiste. El control vuelve a las manos del programador, que, por un lado, libera las manos y, por otro, requiere comprensión al usarlo. La discusión a continuación se centrará en tal uso de "comprensión", técnicas que en la primera pareja requieren conciencia y disciplina, pero luego se perciben como algo natural.


Sobre tienda y estado


Brevemente sobre estos dos conceptos, para que no haya confusión.


Store redux — , state , state, state, - . ""


State redux-store , , , , , . State . ""


mapStateToProps


connect, , HOC-, store . connect mapStateToProps. mapStateToProps . mapStateToProps ( , ).


1 mapStateToProps.

,


const mapStateToProps = () => {
  return {
    units: [1, 2, 3]
  }
}


const UNITS = [1, 2, 3];

const mapStateToProps = () => {
  return {
    units: UNITS
  }
}

, react-redux , . mapStateToProps . mapStateToProps shallowEqual ( ). .. , , .


, [1, 2, 3], shallowEqual . , .


, return- mapStateToProps , . , , - . UNITS - selectUserUnits(state, userId). .


reselect


.. state — , : state.todos[42].title. , . , . , redux .


reselect — , . -, readme , . -, reselect . -, ( , ) .


2 reselect , .

. , , , mapStateToProps.


reselect . , :


export const selectPriceWithDiscountByProductId = (state, id) => {
  const {price, discount} = state.product[id];

  return {price, discount};
};

export const selectTagsByProductId = (state, id) => state.product[id].tags || [];

, mapStateToProps, . , tags. , reselect ( faiwer — :) ).


, :


const EMPTY_ARRAY = Immutable([]);

export const selectTagsByProductId = (state, id) => state.product[id].tags || EMPTY_ARRAY;

3 reselect , .

. . const selectUserById = (state, id) => state.user[id] ,


reselect . , createSelector, .


createSelector(...inputSelectors | [inputSelectors], resultFunc)

inputSelectors — , . resultFunc, .


// selectors.js

const selectUserTagById = (state, userId) => state.user[userId].tag;
const selectPictures = state => state.picture;

const selectRelatedPictureIds = createSelector(
  selectUserTagById,
  selectPictures,
  (tag, pictures) => (
     Object.values(pictures)
       .filter(picture => picture.tags.includes(tag))
       .map(picture => picture.id)
  )
)

, , , . , .


, reselect , :


  • ( shallowEqual), . , id , reselect
  • inputSelectors ( shallowEqual), . , - , reselect selectUserTagById selectPictures. pictures tag, reselect .

4 .

selectUser({user}) inputSelectors


. reselect, : 1. , . , . , RelatedPictures,


// RelatedPicturesContainer.js

import {connect} from 'react-redux';
import {RelatedPictures} from '../components';
import {selectRelatedPictureIds} from '../selectors';

const mapStateToProps = (state, {userId}) => {
  return {
    pictureIds: selectRelatedPictureIds(state, userId)
  }
};

export default connect(mapStateToProps)(RelatedPictures);


const RelatedPicturesList = ({userIds}) => (
  <div>
    {Array.isArray(userIds) && (
      userIds.map(id => <RelatedPictureContainer userId={id} />
    )}
  </div>
)

RelatedPicturesList , RelatedPictureContainer mapStateToProps pictureIds, selectRelatedPictureIds userId . , , RelatedPictures ShouldComponentUpdate, .


reselect


5 .

, mapStateToProps , . react-redux , mapStateToProps, , mapStateToProps


// selectors.js
const selectUserTagById = (state, id) => state.user[id].tag;
const selectPictures =  (state, id) => state.picture;

const createRelatedPictureIdsSelector = () => createSelector(
  selectUserTagById,
  selectPictures,
  (tag, pictures) => (
     Object.values(pictures)
       .filter(picture => picture.tags.includes(tag))
       .map(picture => picture.id)
  )
)

// RelatedPicturesContainer.js

import {connect} from 'react-redux';
import {RelatedPictures} from '../components';
import {createRelatedPictureIdsSelector} from '../selectors';

const createMapStateToProps = () => {
  const selectRelatedPictureIds = createRelatedPictureIdsSelector();

  return (state, {userId}) => {
    return {
      pictureIds: selectRelatedPictureIds(state, userId)
    };
  };
};

export default connect(createMapStateToProps)(RelatedPictures);

RelatedPicturesContainer selectRelatedPictureIds. 1. - userId, . . , react-, relatedPictureIds , GC .


. "? ? , , ?". re-reselect, . , mapStateToProps


6 re-reselect

. , . , , , , , Node.js Server Side Rendering. , , , .


connect


mapStateToProps. , connect ' .


connect(mapStateToProps, mapDispatchToProps, mergeProps, options)

, react-redux . , mapStateToProps (state), . mapDispatchToProps.


7 mapStateToProps mapDispatchToProp connect'

, mergeProps . mergeProps ( ) mapStateToProps mapDispatchToProps. , , , . . , : connect(mapStateToProps, null, x => x).


react-redux . , mapStateToProps null, ( , ). , . mapStateToProps ( ), mergeProps .


, options connect. . , mapStateToProps, mapDispatchToProps mergeProps shallowEqual. . , mapStateToProps.


8 connect, . , shouldComponentUpdate — .


redux . -, . , .


React-redux — . , ( MVVM). , , . , , . shouldComponentUpdate (useRef ).


Bueno, en la muy, muy conclusión. Espero que el lector encuentre útiles al menos un par de consejos, lo que significa que no fue en vano lo que escribió. Todo castor)


All Articles