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.

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, .
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,
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
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)
)
)
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)