SOLID рджреНрд╡рд╛рд░рд╛ рд░рд┐рдбрдХреНрд╕ рд▓рд┐рдЦрдирд╛

рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ рд╣рдо рд▓реЗрдЦрди рдХрд╛рд░реНрдпреЛрдВ рдФрд░ reducer рдкрд░ рд╕реНрдкрд░реНрд╢ рдХрд░реЗрдВрдЧреЗред рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ 'рдкреНрд░рд╡рд╛рд╣' рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВ (рдЖрдЧреЗ, рд╣рдо рд╕рдм рдХреБрдЫ рдлрд┐рд░ рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдорд╛рд░рд╛ рдХреЛрдб SOLID рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рд╕реЗ рдорд┐рд▓рддрд╛ рд╣реЛ)ред

1. рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ (рдпрд╣рд╛рдВ рд╣рдо рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдирд╛рдо рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ)

export const REQUEST_DATA_PENDING = "REQUEST_DATA_PENDING"; export const REQUEST_DATA_SUCCESS = "REQUEST_DATA_SUCCESS"; export const REQUEST_DATA_FAILED = "REQUEST_DATA_FAILED"; export const PROFILES_PER_PAGE = "PROFILES_PER_PAGE"; export const CURRENT_PAGE = "CURRENT_PAGE"; 

2. рдПрдХ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдЬрд╣рд╛рдВ рд╣рдо рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ (рдпрд╣рд╛рдВ рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЦрд╛рддреЛрдВ, рдФрд░ рдкреГрд╖реНрдард╛рдВрдХрди рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ redux-thunk рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдЖрдЧреЗ рд╣рдо рдЗрд╕реА рддрд░рд╣ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░реЗрдВрдЧреЗ):

 export const requestBigDataAction = () => (dispatch) => { fetchingData(dispatch, BIG_DATA_URL, 50); } export const changeCurrentPAGE = (page) => ({ type: CURRENT_PAGE, payload: page }) function fetchingData(dispatch, url, profilesPerPage) { dispatch({type: REQUEST_DATA_PENDING}); fetch(url) .then((res) => { if(res.status !== 200) { throw new Error (res.status); } else { return res.json(); } }) .then((data) => {dispatch({type: REQUEST_DATA_SUCCESS, payload: data})}) .then(() => dispatch({type: PROFILES_PER_PAGE, payload: profilesPerPage})) .catch((err) => dispatch({type: REQUEST_DATA_FAILED, payload: ` . ${err.message}`})); } 

3. рд╣рдо reducer рд▓рд┐рдЦрддреЗ рд╣реИрдВ

 import { REQUEST_DATA_PENDING, REQUEST_DATA_SUCCESS, REQUEST_DATA_FAILED, PROFILES_PER_PAGE, CURRENT_PAGE } from '../constants/constants'; const initialState = { isPending: false, buffer: [], data: [], error: "", page: 0, profilesPerPage: 0, detailedProfile: {} } export const MainReducer = (state = initialState, action = {}) => { switch(action.type) { case REQUEST_DATA_PENDING: return Object.assign({}, state, {isPending: true}); case REQUEST_DATA_SUCCESS: return Object.assign({}, state, {page : 0, isPending: false, data: action.payload, error: "", detailedProfile: {}, buffer: action.payload}); case REQUEST_DATA_FAILED: return Object.assign({}, initialState, {error: action.payload}); case PROFILES_PER_PAGE: return Object.assign({}, state, {profilesPerPage: action.payload}); case CURRENT_PAGE: return Object.assign({}, state, {page: action.payload}); default: return state; } } 

4. рд╕реНрдЯреЛрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ (рдорд┐рдбрд▓рд╡реЗрдпрд░ thunkMiddleware рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ)

 import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import {createStore, applyMiddleware} from 'redux'; import {Provider} from 'react-redux'; import thunkMiddleware from 'redux-thunk'; import {MainReducer} from './reducers/mainReducer'; const store = createStore(MainReducer, applyMiddleware(thunkMiddleware)); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root')); 


5. рдШрдЯрдХ рдХреЛ рд░рд┐рдбреНрдпреВрдХреНрд╕ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ
 const mapDispatchToProps = (dispatch)=>{ return { onRequestBigData: (event) =>{ dispatch(requestBigDataAction()); } } }; 

рдкреЗрдЬреЗрд╢рди рдмрдЯрди рдХреЛ Redux рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ

 const mapDispatchToProps = (dispatch)=>{ return { onChangePage: (page) =>{ dispatch(changeCurrentPAGE(page)); } } }; 

рд╕рдорд╕реНрдпрд╛: рд╣рдорд╛рд░рд╛ рд░реЗрдбреНрдпреВрд╕рд░ рдПрдХ рдмрдбрд╝рд╛ рд╕реНрд╡рд┐рдЪ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдПрдХ рдирдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рдпрд╛ рдЙрд╕рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдмрджрд▓рддреЗ рд╣реБрдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд░рд┐рдбреНрдпреВрд╕рд░ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдПрд╕рдУрдПрд▓рдЖрдИрдбреА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ (рдПрдХрдорд╛рддреНрд░ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдФрд░ рдЦреБрд▓реЗрдкрди / рдирд┐рдХрдЯрддрд╛ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд) рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИред

рд╕рдорд╛рдзрд╛рди: рдмрд╣реБрд░реВрдкрддрд╛ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдЧрд╛ред рдкреНрд░рддреНрдпреЗрдХ рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрди рд╡рд┐рдзрд┐ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рдЕрдкрдбреЗрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧрд╛ рдФрд░ рдЕрдкрдбреЗрдЯ рдХреА рдЧрдИ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░реЗрдЧрд╛ред рддрдм рд╣рдорд╛рд░реЗ reducer рдлрд╛рд░реНрдо рд▓реЗ рдЬрд╛рдПрдЧрд╛

 export const MainReducer = (state = initialState, action) => { if(typeof action.execute === 'function') return action.execute(state); return state; }; 

рдЕрдм рдПрдХ рдирдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЬреЛрдбрд╝рддреЗ рд╕рдордп, рд╣рдореЗрдВ reducer рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдпрд╣ рдПрдХ рд╡рд┐рд╢рд╛рд▓ рд░рд╛рдХреНрд╖рд╕ рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред

рдЗрд╕рдХреЗ рдмрд╛рдж, Redux-thunk рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ рдФрд░ рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВ

 import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import {createStore} from 'redux'; import {Provider} from 'react-redux'; // import thunkMiddleware from 'redux-thunk'; import {MainReducer} from './reducers/mainReducer'; const store = createStore(MainReducer); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root')); 

рдЬреБрдбрд╝реЗ рдШрдЯрдХ рдкрд░ рдЬрд╛рдПрдВ, рдЬрд┐рд╕рдХреА рдХреНрд░рд┐рдпрд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реИ (рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рд╕рд╣реА рдХрд░рдирд╛ рд╣реЛрдЧрд╛)

 const mapDispatchToProps = (dispatch)=>{ return { onRequestBigData: (event) =>{ requestBigDataAction(dispatch); }, } }; 

рдФрд░ рд╕реНрд╡рдпрдВ рдХреНрд░рд┐рдпрд╛рдУрдВ рдкрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ рдФрд░ рдЙрди рдкрд░ рдирд┐рд╖реНрдкрд╛рджрди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ

 const type = 'bla-bla'; const requestDataPending = {execute: state => ({...state, isPending: true}), type}; const requestDataSuccess = payload => ({ execute: function (state) { return ({...state, page : 0, isPending: false, data: payload, error: "", detailedProfile: {}, buffer: payload}) }, type}) const profilesPerPageAction = profilesPerPage => ({ execute: state => ({...state, profilesPerPage: profilesPerPage}), type }); const requestDataFailed = errMsg => state => ({...state, error: ` . ${errMsg}`}); function fetchingData(dispatch, url, profilesPerPage) { dispatch(requestDataPending); fetch(url) .then((res) => { if(res.status !== 200) { throw new Error (res.status); } else { return res.json(); } }) .then((data) => {dispatch(requestDataSuccess(data))}) .then(() => dispatch(profilesPerPageAction(profilesPerPage))) .catch((err) => dispatch(requestDataFailed(err.message))); } export const requestBigDataAction = (dispatch) => { fetchingData(dispatch, BIG_DATA_URL, 50); } export const changeCurrentPAGE = page => ({ type, execute: state => ({...state, page}) }) 

рдиреЛрдЯ: рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдирд╣реАрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЕрдм рд╣рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдкреБрдирд╢реНрдЪ: рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдордиреЗ рдПрд╕рдЖрд░рдкреА рдФрд░ рдУрд╕реАрдкреА, рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рддреНрдпрд╛рдЧ рджрд┐рдпрд╛ рдФрд░ рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреЛ рдЕрдзрд┐рдХ рд╕реНрд╡рдЪреНрдЫ рдФрд░ рдмрдирд╛рдП рд░рдЦрд╛ред

Source: https://habr.com/ru/post/hi475194/


All Articles