React에서 사용하는 방식과 거의 유사하다.
react Reducer
npm i redux
npm i react-redux
추후 dispatch 할 때 type:으로 지정될 값을 작성해놓는다.
[commons/actionTypes]
export const 액션명 = "액션명"
export const DELETE_FAVORITES = "FETCHED_DELETE_FAVORITES";
export const ADD_FAVORITES = "FETCHED_ADD_FAVORITES";
리듀서가 포함되어있는 JS 파일 생성
[reducers/index]
import { combineReducers } from "redux";
import * as actionTypes from "../commons/actionTypes";
const initialState = {
num: 0,
diff: 1
}
function diff(state = initialState, action){
switch(action.type){
case actionTypes.DIFF:
return {...state} ;
}
}
function number(state = initialState, action) {
switch (action.type) {
case actionTypes.NUMBER:
return {...state} ;
case actionTypes.DELETE_NUMBER:
return {...state, num: state.num-1 } ;
case actionTypes.ADD_NUMBER:
return {...state, num: state.num+1 } ;
default:
return state;
}
}
const appReducer= combineReducers({
number
})
const rootReducer = (state, action) => {
return appReducer(state,action)
}
export default rootReducer;
[app.jsx]
import React from 'react';
import { Text, View } from 'react-native';
import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'remote-redux-devtools';
import rootReducer from './reducers';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationContainer } from '@react-navigation/native';
import Number from './screens/Number';
export const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
const Stack = createNativeStackNavigator();
function App(): JSX.Element {
return (
<Provider store={store}>
<NavigationContainer>
<Stack.Navigator initialRouteName='Num'>
<Stack.Screen name='Num' component={Number} />
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
}
export default App;
store는 위와 같이
export const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
return(
<Provider store={store}>
</Provider>
)
으로 작성하거나
const composeEnhancers = composeWithDevTools({
realtime: true,
name: "space",
hostname: "localhost",
port: 8001
});
const composeStoreWithMiddleware = composeEnhancers(applyMiddleware(thunk))(
createStore
);
return(
<Provider store={composeStoreWithMiddleware(rootReducer)}>
</Provider>
)
와 같이 작성한다.
데이터를 처리하고 해당 값을 타 컴포넌트(NumberCon)에 전달하는 역할을 하는 컨테이너 컴포넌트 작성
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import * as actionTypes from '../commons/actionTypes'
import NumberCon from './NumberCon';
const Number = ({navigation}) => {
const {num} = useSelector(state=>state.number)
// state.number의 number는 리듀서명 number이다.
const dispatch = useDispatch()
const decNum = () => dispatch({type:actionTypes.ADD_NUMBER})
const incNum = () => dispatch({type:actionTypes.DELETE_NUMBER})
// type:ADD_NUMBER의 ADD_NUMBER는 액션타입이다.
return (
< NumberCon num={num} decNum={decNum} incNum={incNum} />
)
}
export default Number
[actions/index]
1) Data get , dispatch
export function decNum() {
return dispatch => {
axios
.get(`주소`)
.then(response => {
dispatch({type: actionTypes.ADD_NUMBER});
})
.catch(e => { processByErrorCode(e); });
};
}
2) Data 삭제 , dispatch
export function incNum(id) {
return async dispatch => {
try {
const response = await axios.delete(
`주소`,
'',
{ headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cache-Control': 'no-cache',
}},
);
dispatch({type: actionTypes.DELETE_NUMBER});
} catch (e) {
processByErrorCode(e);
}
};
}
리덕스 스토어에 접근하지 않고 필요한 값은 props로 전달 받아, 화면을 설계하는 프리젠테이셔널 컴포넌트 작성
import { Button, StyleSheet, Text, View } from 'react-native'
import React from 'react'
const NumberCon = ({num, decNum,incNum}) => {
return (
<View>
<Text>{num}</Text>
<Button title='plus' onPress={decNum}/>
<Button title='minus' onPress={incNum}/>
</View>
)
}
export default NumberCon
const styles = StyleSheet.create({})