วันเสาร์ที่ 31 ตุลาคม พ.ศ. 2563

[React Native] Redux

Redux

- ใช้แชร์ State แบบ Global ให้ทุก Component เข้าถึงได้
- Component ต้องเรียกใช้ Action ในการแก้ไขข้อมูลใน State Global โดยตรง
- ใช้ Logger ในการ Track ได้จะเห็น prev state, action, next state

npm install redux redux-logger redux-thunk react-redux

redux react-redux : ลง redux และใช้ react-redux
redux-logger : ใช้ track การเปลี่ยนแปลงข้อมูล
redux-thunk : เพื่อให้ใช้งาน asynchronous ได้

Flow

graph LR; a([State])--defines-->b([UI]); b([UI])--triggers-->c([Actions]); c([Actions])--sent to-->d([Reducer]); d([Reducer])--updates-->e([Store]); e([Store])--contains-->a([State]);

สร้าง Constant.js ก่อนเพื่อกำหนด Action ต่าง ๆ

graph LR; a([State])--defines-->b([UI]); b([UI])--triggers-->c([Actions]); c([Actions])--sent to-->d([Reducer]); d([Reducer])--updates-->e([Store]); e([Store])--contains-->a([State]); style c fill:#fdfd96

file: /src/Constant.js
// กำหนดก่อนว่าจะมีการกระทำแบบไหนบ้าง ในตัวอย่าง สร้าง ACTION - ADD, REM, CLR

export const ACTION_ADD = 'ACTION_ADD'
export const ACTION_REM = 'ACTION_REM'
export const ACTION_CLR = 'ACTION_CLR'

file: /src/action/calculator.action.js
// import Constant ของ ACTION ที่เรากำหนดไว้
import {ACTION_ADD, ACTION_REM, ACTION_CLR} from "../Constant";

// ส่วนที่ส่งไปยัง เป็น Function Return Object ไปยัง Reducer
export const setStateToADD = () => ({
	type: ACTION_ADD
});

export const setStateToREM = () => ({
	type: ACTION_REM
});

export const setStateToCLR = (payload) => ({
	type: ACTION_CLR,
        payload: payload
});

// ส่วนที่เป็น Function ให้ UI เรียกใช้งาน
export const add = () => {
    // do something
    return dispatch => {
    	dispatch(setStateToADD());
    }
}

export const rem = () => {
    // do something
    return dispatch => {
    	dispatch(setStateToADD());
    }
}

export const clear = (payload) => {
    // do something
    playload = 0;
    
    // ส่ง dispatch (redux-thunk) เป็น callback ไปยัง reducer
    return dispatch => {
        // ส่งค่าไปอัพเดตที่ State
    	dispatch(setStateToCLR(payload);
    }
}

Reducer

graph LR; a([State])--defines-->b([UI]); b([UI])--triggers-->c([Actions]); c([Actions])--sent to-->d([Reducer]); d([Reducer])--updates-->e([Store]); e([Store])--contains-->a([State]); style d fill:#fdfd96

file: /src/reducer/calculator.reducer.js
// import Constant ของ ACTION ที่เรากำหนดไว้
import {ACTION_ADD, ACTION_REM, ACTION_CLR} from "../Constant";

// initial state, ใช้สร้าง State
const initialState = {
	count: 0,
}

// ทำการสร้าง State และรับค่าจาก Action มา
export default (state = initialState, {type, payload}) => {

    // รับค่าจาก Action ว่าเป็น Type อะไร
	switch(type) {
    
    	case ACTION_ADD:
            // { State ของเก่า, State ตัวที่ต้องการแก้ไข}
        	return { ...state, count: state.count + 1}
            
        case ACTION_REM:
        	return { ...state, count: state.count - 1 }
            
    	case ACTION_CLR:
        	return { ...state, count: payload}
            
            // ไม่ต้องกับ Action ไหนเลย
        default:
        	return state;
    }
}

file: /reducer/index.js
// import redux และ reducer ที่เราสร้างขึ้น
import {combineReducers} from 'redux';
import calculatorReducer from './calculator.reducer';

// ทำการ combineReducers ถ้ามีตัวอื่นให้ใช้ , คั่น
export default combineReducers({calculatorReducer});

สร้าง store ไว้ในไฟล์ index.js

graph LR; a([State])--defines-->b([UI]); b([UI])--triggers-->c([Actions]); c([Actions])--sent to-->d([Reducer]); d([Reducer])--updates-->e([Store]); e([Store])--contains-->a([State]); style e fill:#fdfd96

file: /index.js
// redux need !! ต้อง import react มาด้วย
import React from 'react';

...

// redux import begin

// --- create store, middleware และ provider
import {createStore, applyMiddleware} from 'redux';
import {Provider} from 'react-redux';

// --- middleware logger และ thunk
import logger from 'redux-logger';
import thunk from 'redux-thunk';

// --- reducers ที่เราสร้างและ combineReducers ไว้
import reducers from './src/reducers';

// redux import end

...

const store = createStore(reducers, applyMiddleware(logger, thunk));
const ReduxApp = () => (
    <Provider store={store}>
        <App />
    </Provider>
)

...

AppRegistry.registerComponent(appName, () => ReduxApp);
// --- ตัว
// AppRegistry.registerComponent(appName, () => App);

เอาไปใช้งานใน Component

graph LR; a([State])--defines-->b([UI]); b([UI])--triggers-->c([Actions]); c([Actions])--sent to-->d([Reducer]); d([Reducer])--updates-->e([Store]); e([Store])--contains-->a([State]); style a fill:#fdfd96; style b fill:#fdfd96;

file: /x-component.js
...

import {userSelector,useDispatch} from "react-redux";
import * as calculatorActions from "../../actions/calculator.action";

const App = (props) => {
    const calculatorReducer = useSelector(({calculatorReducer}) => calculatorReducer);
    const dispatch = userDispatch();
    
    ...
    
    return (
    	<View>
            <Text onPress={()=>dispatch(calculatorActions.clear(-1))}>
            	Value: {calculatorReducer.count}
            </Text>
        </View>
    )
}




ขอบคุณข้อมูลจาก
https://www.youtube.com/watch?v=i-PnAoNr4Js&list=PLjPfp4Ph3gBpkLZtvuEMpPMtGsPJh7E4_

ไม่มีความคิดเห็น:

แสดงความคิดเห็น