2. Redux Dispatch


Dispatch

React-Redux

뷰(컴포넌트)에서 Dispatch를 통해 특정한 action을 실행시키고, 그에 따라 reducer가 실행된다.
그리고 state가 지정해놓은 규칙에 따라 변경되어 구동하고 있는 컴포넌트들에 반환될 것이다.


mapDispatchToProps

나는 userObject의 업데이트를 store에서 관리하고, 이를 필요한 컴포넌트에 뿌려주고싶다.

따라서 App.jsx에서 onAuthStateChanged 함수가 실행됐을 때 snapshot 함수 내에서 dispatch를 발동시켜줬다. 이에 따라 로그인을 했을 때, 혹은 유저 정보에 변화가 생겼을 때 userObject가 snapshot에 의해 업데이트 되고, 이후에 변경된 값이 dispatch를 통해 리듀서에 전달된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// App.js

const userSnapshot = async (user) => {
const userRef = doc(db, 'Users', auth.currentUser.email);
// 유저 이름이 등록되어있지 않을 때
if (!user.displayName) {
onSnapshot(userRef, async (snapshot) => {
const newUserObject = {
displayName: 'User',
...snapshot.data(),
};
setUserObject(newUserObject);
// updateUser 디스패치가 발동된다.
props.updateUser(newUserObject);
return setIsLoading(false);
});
}
// 등록되어 있을 때
onSnapshot(userRef, async (snapshot) => {
setUserObject(snapshot.data());
// updateUser 디스패치가 발동된다.
props.updateUser(snapshot.data());
return setIsLoading(false);
});
};
// onAuthStateChanged를 통해 유저정보 변화를 listening한다
useEffect(() => {
onAuthStateChanged(auth, (user) => {
if (user) {
userSnapshot(user);
} else {
setUserObject(null);
setIsLoading(false);
}
});
}, []);

// mapStateToProps는 구독중인 state를 받아올 수 있도록 한다.
const mapStateToProps = (state) => {
return {
user: state.user,
};
};
// dispatch
const mapDispatchToProps = (dispatch) => {
return {
// updateUser라는 이름으로 updateUser() 디스패치를 실행시켜 응답을 받아온다.
updateUser: (user) => dispatch(updateUser(user)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(App);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// .../redux/authentication/userUpdate.js

// Action
export const updateUserAction = 'UPDATE_USER';
// Action Creator
export const updateUser = (user) => ({ type: updateUserAction, payload: user });

const initialState = { user: {} };

function updateUserReducer(state = initialState, action) {
// reducer가 이 action을 참조하는지 체크
if (action.type === updateUserAction) {
// 만약 참조한다면, state를 복사
console.log(action.payload);
return {
...state,
// 그리고 새로운 값을 업데이트 해준다.
// payload에 담긴 값을 spread operator를 통해 덮어준다.
user: { ...state.user, ...action.payload },
};
}
// 위 조건에 해당되지 않으면 그냥 기존 state값을 리턴해준다.
return state;
}
export default updateUserReducer;

미들웨어 사용하기

loggercomposeWithDevTools를 통해 조금 더 쉽게 redux의 프로세스와 상태를 확인할 수 있다.

1
2
3
4
5
6
7
8
9
// .../src/index.js

import logger from 'redux-logger';
import { composeWithDevTools } from 'redux-devtools-extension';

const store = createStore(
updateUserReducer,
composeWithDevTools(applyMiddleware(logger))
);

콘솔 창에 이렇게 보기 쉽게 정리되어 찍힌다


Author

Hoonjoo

Posted on

2022-01-05

Updated on

2022-01-06

Licensed under

Comments