오티스의개발일기

[REACT NATIVE] IMMER 사용하기 + REDUX 추가설명 -git첨부- 본문

개발/react-native

[REACT NATIVE] IMMER 사용하기 + REDUX 추가설명 -git첨부-

안되면 될때까지.. 2022. 12. 20. 17:22
728x90


다음글 >

2022.12.21 - [개발/react-native] - [REACT NATIVE] Redux-Saga 프로젝트 시작하기

 

[REACT NATIVE] Redux-Saga 프로젝트 시작하기

< 이전글 2022.12.20 - [개발/react-native] - [REACT NATIVE] IMMER 사용하기 + REDUX 추가설명 [REACT NATIVE] IMMER 사용하기 + REDUX 추가설명 < 이전글 2022.12.20 - [개발/react-native] - [REACT NATIVE] REDUX 미들웨어 그리고 클

otis.tistory.com



< 이전글

2022.12.20 - [개발/react-native] - [REACT NATIVE] REDUX 미들웨어 그리고 클라이언트단부터의 로직의 흐름

 

[REACT NATIVE] REDUX 미들웨어 그리고 클라이언트단부터의 로직의 흐름

저번글에서 react native에서 redux를 추가하는방법을 배워보았다. redux-saga를 공부를 하고있는데 아무리봐도 도저히 이해가 안가는부분이 있었다. 일단은 미들웨어에서 어떻게 처리하는지도 모르겠

otis.tistory.com


 

이번에 react-native 프로젝트를 시작하고 redux에 대해 공부하고

프로젝트에 적용을 시켰을때 몇가지가 너무 거슬렸다.

 

다행히 immer라는 api를 알게되었고 또한  redux toolkit을 알게되어

이렇게 복사를 그만두고 프로젝트에 적용을 시켰다

 

내가 제대로 하고있는지 궁금해 새로운 프로잭트를 시작하였고

redux를 적용시키고 또한 데이터 흐름을 파악하기 시작하였다.

 

글을 시작하기전에 콘솔로그로 찍으며 알게된 사실을 먼저 적고 immer를 적용시켜보겠다.

 

 

/src/screen/LoginScreen.js

const LoginScreen = () => {
    const dispatch = useDispatch();
    const user = useSelector(state => state.userReducer);
    //  state.userReducer
    // state 는 전체 이니셜스테이트 데이터
    // state.userReducer = ../reducers/rootReducer 안에  userReducer << 이친구를 가르키고있다. : userReducer,

    const loginApi = () => {
        dispatch(logInRequest({
            nickName: 'dhstjrxo123',
            password: 'dhstjrco123!'
        }));
    }

    const logOutApi = () => {
        dispatch(logOutRequest({
        }));
    }
    return (
        <View>
            {!user.user ?
                <Button title={"로그인"} onPress={loginApi}></Button>
                : <Button title={"로그 아웃"} onPress={logOutApi}></Button>
            }

            <View>
                {
                    user.loading ? <Text>로그인인중</Text> : user.user ? <Text>{user.user.nickName}</Text> : <Text>로그인해주세요</Text>
                }

            </View>
        </View>
    );
}

위에 보이는

const user = useSelector(state => state.userReducer);

이부분에 state와 userReducer가 뭔지몰랐다.

 

다른사람들은 알고있을수도 있겠지만 여러 코드를 보고

여러코드를 복사해가며 틀어보고 하였기에

저부분을 reducer라고 지칭했던 프로젝트는 여태 없었다.

그래서 나는 당연히 state. 을 찍는 순간 reducer에 접급한줄알고 

한 2시간동안 삽질을 해왔다....

 

이 프로잭트 안에는 rootReducer가 있다

/src/reducers/rootReducer.js

import {userReducer} from "../reducers/userReducer"; // 만든 리듀서'

const rootReducer = combineReducers({
    userReducer : userReducer,
});

저기 상단에 useReducer << 바로 이친구를 지칭: userReducer 하는 것이였다.

 

다들 본인처럼 삽질그만하고 이글을 읽고 탈출하길 빈다.

 

 

 

이제 본론으로 넘어가 immer 를 적용시켜보겠다.

 

/src/reducers/userReducer.js

const userReducer = (state = initialState, action) => {
    return produce(state, (draft) => {
        const {type, payload} = action;
        switch (type) {
            case USER_ACTION_TYPE.USER_LOADING:
                return {
                    ...state,
                    loading: true
                }
            case USER_ACTION_TYPE.USER_LOG_IN_REQUEST:
                return {
                    ...state,
                    loading: true
                }
            case USER_ACTION_TYPE.USER_LOG_IN_SUCCESS:
                return {
                    ...state,
                    loading: false,
                    user: payload
                }
            case USER_ACTION_TYPE.USER_LOG_IN_FAILURE:
                return {
                    ...state,
                    loading: false
                }
            case USER_ACTION_TYPE.USER_LOG_OUT_REQUEST:
                return {
                    ...state,
                    loading: true
                }
            case USER_ACTION_TYPE.USER_LOG_OUT_SUCCESS:
                return {
                    ...state,
                    loading: false,
                    user: null,
                }
            case USER_ACTION_TYPE.USER_LOG_OUT_FAILURE:
                return {
                    ...state,
                    loading: false,
                }
            default:
                return state
        }
    })
}

 보아라 얼마나 더러운지....

지금이야 더미데이터로 만든다 하지만 이게 실제 프로젝트였으면 

switch 지옥에 복사지옥

추가적으로 조금더 깊은 데이터 

예를들어 오브젝트안에 오브젝트와 배열이 난무하는 그런 데이터를 다뤘다면

애초에 리엑트를 시작안했을지도 모른다...

 

이미 저것만해도 고구마를 100개 먹은 기분이였다...

 

뭐어쨌든 이제 설치하고 적용시켜보겠다.

 

1. npm 으로  immer 설치

잊지말자 !   

cd 자신의 프로젝로!

 npm install immer

 

 nextState = produce(prevState, (draft) => {})

기본적인 immer의 형태이다.

produce를 제공하고있고

저기 보이는 preveState는 말그대로 변경전 State다 

그말은 즉슨 이제 

...state 를 안해도 immer에서 자동으로 불변의 법칙을 지켜주고 있다 이말이다....

 

속이 내려간다..

 

 

이제 코드에 적용해보겠다.

 

 

2. 코드 적용

 

상단에 import를 해준다 

import {produce} from 'immer'

 

이런식으로 object에서 데이터 꺼내듯 쓰면된다.

또한 바꾸고 싶은것만 바꾸면 된다.

 

예를들어

  user: {

      name: '나',

      age : 15

}

 

 

draft.age = 20;

 

이런식으로 하면 name은 그대로 보존된다.

또한 

위에는 preVState라고 적어놨는데

본인은 state가 편해 state라고 명칭해놓았다.

 

state = 변경전 데이터

draft = 변경전 데이터 복사본.

 

참고로 더이상 return은 쓰지 않아도 된다 immer가 다~ 알아서 해준다.

const userReducer = (state = initialState, action) => {
    return produce(state, (draft) => {
        const {type, payload} = action;
        switch (type) {
            case USER_ACTION_TYPE.USER_LOADING:
                draft.loading = true
            case USER_ACTION_TYPE.USER_LOG_IN_REQUEST:
                draft.loading = true
            case USER_ACTION_TYPE.USER_LOG_IN_SUCCESS:
                draft.user = payload
                draft.loading = true
            case USER_ACTION_TYPE.USER_LOG_IN_FAILURE:
                draft.loading = false
            case USER_ACTION_TYPE.USER_LOG_OUT_REQUEST:
                draft.loading = true
            case USER_ACTION_TYPE.USER_LOG_OUT_SUCCESS:
                draft.user = null
                draft.loading = false
            case USER_ACTION_TYPE.USER_LOG_OUT_FAILURE:
                draft.loading = false
            default:
                return state
        }
    })
}

 

 

작업한 내용은 깃에 올려놓았다.

 

https://github.com/1domybest/react-native-immer.git

 

GitHub - 1domybest/react-native-immer

Contribute to 1domybest/react-native-immer development by creating an account on GitHub.

github.com

 

 

다음 시간에는

 

redux toolkit 에대해 포스팅 하겠다.

728x90
Comments