개발노트

redux 본문

React/project

redux

aloha2jh 2020. 8. 25. 10:36

즉 리덕스는 State를 분배.

리액트의  state를 하나의 store에 모아서 관리하면서,

하나의 state를 여러 컴포넌트에 전달할수 있다.

필요한 state를 골라서 해당컴포넌트에 전달할수 있음

 

store

리덕스만의 state (리액트state)

 

initialState

상태값 전부 여기서 관리

 

action

state를 바꾸는 종류를 정의

( 로그인액션, 회원가입액션, 글쓰기액션...)

 

dispatch

이 액션실행시켜줘 하는 (정의되있는)액션의 실행.

 

reducer

각 액션에 (결과로)따라서 state를 이렇게 바꿔줘 정의

( 로그인액션땐 로그인상태값 on으로, 로그아웃액션땐 로그인상태값off로

로그인때 회원정보값 넣고, 로그아웃때 null로 비우기 같은.)

 

 

ex) user reducer

//reducer/user.js
export const initialState = {
    isLoggedIn: false,
    myInfo:{},
}

export const LOG_IN_REQUEST = 'LOG_IN_REQUEST';   //액션의 이름

export const loginRequestAction = {   //실제 액션 (객체형태의.액션)
    type: LOG_IN_REQUEST,
    data:{ name:'jh' }, 
};

const reducer = ( state=initialState, action ) =>{
	switch(action.type){
    
    	case LOG_IN_REQUEST : {
            return{
                ...state, 
                isLoggingIn:true,
                user: action.data
            }
        }
    }
}
export default reducer;

 

 

 

Root Reducer 

combineReducers를 통해 root reducer 만들기

import { combineReducers } from 'redux';
import user from './user';
import post from './post';

const rootReducer = combineReducers({
    user,
    post,
});

export default rootReducer;

이렇게 하나로 combine한 리듀서들은(user, post reducer) 

루트 리듀서에서(를통해서인가?) 각 initialState에 접근가능해진다.

 

 

 

리덕스를 리액트에 연결

(1) _app.js에 루트리듀서를 불러오고,  설치한react-redux도 provider(컴포넌트)로 불러온다.

import { Provider } from 'react-redux';
import reducer from '../reducers';

provider(컴포넌트)가 redux State를 제공해줌 !

 

최상위 컴포넌트에  store를 제공해주게 되면

하위 컴포넌트들이 전부 store에 접근할수 있게 된다.

 

그래서

(2) 최상위컴포넌트-provider로 설정하고  store를  넘겨준다

 

//_app.js
const myApp = ({ Component, store }) =>{
    return (
        <Provider store={store}> 
          <Head>
              <title>myApp</title 
          </Head>
          <AppLayout>
              <Component />
          </AppLayout>
        </Provider>
    );
}

 

 

next를 쓴다면? withRedux 

next를 사용할경우 next-redux-wrapper를 설치, withRedux를 앱에 적용해주어야 한다.

store 부분을 넣어주는걸 구현하는게 next-redux-wrapper.

 

//_app.js
import withRedux from 'next-redux-wrapper';
...
export default withRedux()( myApp )

next-redux-wrapper를 withRedux로 불러와서,

export 하는부분에 하이오더컴포넌트 고차함수를 사용해서

기존 컴포넌트기능을 확장해줌!

myApp을 withRedux로 확장것

 

 

//_app.js
const myApp = ({ Component, store {/* 여기 */} }) =>{
    return (
        <Provider store={store}> 
        ...
        </Provider>
    );
}

 이렇게 기존앱을 확장함으로써 withRedux가 앱에 props로 store를 넣어주는 기능을 해줌

 

 

store를 어떻게 넣어줄지 정의

//_app.js
import withRedux from 'next-redux-wrapper';
...
export default withRedux(()=>{})( myApp )

 

createStore 에 rootReducer, initalState를 넣어주기

import reducer from '../reducers';
import { createStore } from 'redux'; 

const configureStore = (initialState, options)=>{ 
    const store = createStore(reducer, initialState ); 
    return (store);
};

state+reducer=store

 

 

 

 

>>리액트에서 리덕스 사용하기 - useDispatch로 액션dispatch

 1. 액션이름 가져와서 사용.

import { useDispatch } from 'react-redux'; //(1)
import { LOG_IN } from '../reducer/user'; //(2)

const Hooks = () =>{
  const dispatch = useDispatch();
  ...
  
  useEffect(()=>{
    dispatch({
      type: LOG_IN, //(3)
      data:{name:'jh'}
    });
  },[])
  
}

(1) 액션을 발생(실행)시키기 위해 dispatch를 불러온다.

dispatch변수로 쓸수있게 useDispatch() (액션을 dispatch시키는 함수) 담아줬고

 

(2) 쓰려고하는 액션도 리듀서에서 import해 온다

 

(3)  dispatch함수안에 액션을 넣어서, 사용 즉 해당 로직중에 필요한 액션을 실행시켜 상태값을 변경시킨다.

(이예시 코드에서는 useEffect 안에 의존성배열값도 없이써서, 그냥 로딩될때 LOG_IN 액션을 dispatch시킨다)

 

 

2. 액션객체 가져와서 사용

import { useDispatch } from 'react-redux'; 
import { loginRequestAction } from '../reducer/user';  //

const Hooks = () =>{
  const dispatch = useDispatch();
  ...
  
  useEffect(()=>{
    dispatch(loginRequestAction);  //
  },[])
  
}

 

 

 

리듀서에 정의되어있는 액션객체를 가져와서도 사용이가능하다.

//reducer/user.js
export const loginRequestAction = (data) =>({ 
    type: LOG_IN_REQUEST,
    data, 
})

 

>>리액트에서 리덕스 사용하기 - useSelector로 reducer의 initialState가져오기

import { useDispatch , useSelector } from 'react-redux'; //(1)
import { LOG_IN } from '../reducer/user';  

const Hooks = () =>{
  const dispatch = useDispatch();
  const user = useSelector(state=>state.user); //(2)
  ...
   
  return(
  	<div>user.isLoggedIn && user.myInfo.name </div> //(3) 
  )
}

(1) reducer의 initialState를 가져오기 위해 useSelector를 불러오기

 

(2) useSelector로 원하는 리듀서의 (initialState)state를 가져옴.

state 는 전체state전부를 의미

state.user 거기서 user리듀서에 있는 initialState 만 (필요에의해) 가져온다

 

(3) useSelector를 통해 꺼내온 (initialState)state를 사용.

//reducer/user.js
export const initialState = {
    isLoggedIn: false,
    myInfo:{},
} 

reducer/user에 initialState에 정의 된대로,

(2)에서 받아왔으니까 접근이 가능한것

 

 

 

 

+리덕스에서도 state를 바꿀때 객체를 복사해서 바꿔야 한다

리액트에서 

setState( (prevState) =>{
	return {
    	filed:{...prevState.field }
    }
}

이전상태값을 인자로받아서, 복사해서 덮어씌워 값을변경한것처럼,

 

 

리덕스에서도 (리듀서안)

case ADD_POSTL{
	return{
    	...state,
        mainPosts: [action.data, ...state.mainPosts],
    }
}

(포스트에 ,새로운포스트추가 여서)

이런식으로  상태값을 바꾼다

 

 

'React > project' 카테고리의 다른 글

nodemon  (0) 2020.08.27
redux 설치  (0) 2020.08.25
back 서버실행  (0) 2020.08.20
back 세팅  (0) 2020.08.20
eslint 추가  (0) 2020.08.12