рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ 2020 рдореЗрдВ Redux рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреНрдпреЛрдВ рдХреА рдЬрд╛рдПрдЧреАред рдЖрдЦрд┐рд░рдХрд╛рд░, рд░рд╛рдЬреНрдп рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдорд╣рд╛рди рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ ( рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП )ред рдЖрдЦрд┐рд░рдХрд╛рд░, Redux рд╕реЗ рдкреНрдпрд╛рд░ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рдЧрднрдЧ рдПрдХ рджрд░реНрдЬрди рдХрд╛рд░рдг рд╣реИрдВ, рдЬрд┐рдирдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдИ рд▓реЗрдЦ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ, рдФрд░ рдХрдИ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рдИ рдЧрдИ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдХреБрдЫ рдЙрд╕рд╕реЗ рджреВрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЖрдк рдЙрд╕ рдкрд░ рдПрдХ рдмрдбрд╝реА, рдХрд╛рд░реНрдпрд╛рддреНрдордХ, рд╕рдорд░реНрдерд┐рдд рдФрд░ рддреЗрдЬ рд╡реЗрдмрд╕рд╛рдЗрдЯ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ ред рдиреАрдЪреЗ рдореИрдВ рдЙрди рддрдХрдиреАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдБрдЧрд╛ рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛-рд░рд┐рдбрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИрдВред рджрд┐рд▓рдЪрд╕реНрдк? рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред

рдЕрд╕реНрд╡реАрдХрд░рдг рдРрд╕реЗ рд╡реНрдпрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕рдиреЗ рдзреНрдпрд╛рди рд╕реЗ рдкреНрд░рд▓реЗрдЦрди рдкрдврд╝рд╛ рд╣реИ, рдХрд╡рд░ рдЯреВрдЯрдиреЗ рдХреА рдШрдЯрдирд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред рдЖрдкрдХрд╛ рдХрдкреНрддрд╛рди
рдирд┐рдЬреА рддреМрд░ рдкрд░, рдореБрдЭреЗ Redux рдмрд╣реБрдд рдкрд╕рдВрдж рд╣реИред рд╕рд╛рджрдЧреА рдФрд░ рдЕрддрд┐рд╕реВрдХреНрд╖реНрдорд╡рд╛рдж рдХреЗ рд▓рд┐рдПред рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛрдИ рдЬрд╛рджреВ рдирд╣реАрдВ рдХрд░рддрд╛ред рдЬрд╣рд╛рдВ рдХреЛрдИ рдЬрд╛рджреВ рдирд╣реАрдВ рд╣реИ, рд╡рд╣рд╛рдВ рдЧрд▓рддреА рд╕реЗ рдХрд┐рд╕реА рдЪреАрдЬ рдХреЛ рддреЛрдбрд╝рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рди рдХрд┐ рдпрд╣ рдЬрд╛рдирдирд╛ рдХрд┐ рдЖрдк рдХреНрдпрд╛ рдереЗред рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рд▓реМрдЯрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рддрд░рдл, рд╣рд╛рдереЛрдВ рдХреЛ рдореБрдХреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░реЗ рдкрд░, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдиреАрдЪреЗ рджреА рдЧрдИ рдЪрд░реНрдЪрд╛ рд╕рд┐рд░реНрдл рдРрд╕реЗ "рд╕рдордЭ" рдЙрдкрдпреЛрдЧ - рддрдХрдиреАрдХреЛрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдЧреА рдЬреЛ рдкрд╣рд▓реЗ рдЬреЛрдбрд╝реЗ рдкрд░ рдЬрд╛рдЧрд░реВрдХрддрд╛ рдФрд░ рдЕрдиреБрд╢рд╛рд╕рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдХреБрдЫ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред
рджреБрдХрд╛рди рдФрд░ рд░рд╛рдЬреНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдЗрди рджреЛ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рддрд╛рдХрд┐ рдХреЛрдИ рднреНрд░рдо рди рд╣реЛред
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
).
рдЦреИрд░, рдмрд╣реБрдд, рдмрд╣реБрдд рдирд┐рд╖реНрдХрд░реНрд╖ рдореЗрдВред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдкрд╛рдардХ рдХреЛ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рд╕реБрдЭрд╛рд╡ рдЙрдкрдпреЛрдЧреА рдорд┐рд▓реЗрдВрдЧреЗ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ рд╡реНрдпрд░реНрде рдирд╣реАрдВ рдерд╛ рдЬреЛ рдЙрдиреНрд╣реЛрдВрдиреЗ рд▓рд┐рдЦрд╛ рдерд╛ред рд╕рднреА рдмреАрд╡рд░)