redux
redux는 data 관리를 도와주는 역할을 하기위해 만들어졌다.
store
data를 저장하는 곳
첫번째 argument는 리듀서가 들어가고, 두번째(옵셔널)는 initialState가 들어간다
import { createStore } from 'redux'
let store = createStore(reducer);
store.getState();
현재의 state를 전달해준다.
store.subscribe(함수)
store에 변화가 일어날 때(state값이 변경될 때) 자동으로 실행된다.
store.dispatch
reducer함수를 실행하기 위한 함수,
상태변경을 일으키기 위한 유일한 방법
Action 타입과 payload를 받는다.
countStore.dispatch({ type: "add", text: '텍스트' });
action
앱의 변경사항을 기술하는 평범한 객체
type필드가 있어야한다. reducer에서 action.type으로 분기처리해 수정이 일어나기 때문에
countStore.dispatch({ type: "add", text: '텍스트' });
action creator
중복되는 코드를 방지하기 위한 액션객체를 return해주는 함수
// 수정 전
store.dispatch({
type: ADD,
'a'
});
store.dispatch({
type: ADD,
'b'
});
store.dispatch({
type: ADD,
'c'
});
//action creator
const addTodo = (text) => {
return {
type: ADD,
text
}
}
store.dispatch(addTodo('a'));
store.dispatch(addTodo('b'));
store.dispatch(addTodo('c'));
action type 변수화
문자를 잘못 입력하는 실수를 할 수도 있는데
변수를 만들어서 사용하는경우 실수를해도 콘솔오류가 나기때문에 빠르게 확인할 수있다.
const ADD = 'add';
const DELETE = 'delete';
reducer
data를 수정하는 함수
state를 어떻게 바꿀건지 특정한 함수
reducer가 리턴하는 값이 store에 저장된다.
reducer는 state, action을 인자로 받는다.
action type에 따라 state변경해준다.
// state에 initialState값을 명시해준다.
const reducer = (state = [], action) => {
switch(action.type) {
case 'add':
return [{text: action.text}, ...state]
case 'delete':
return state.filter(todo => todo.id !== action.id)
default:
return state;
}
}
주의할점
- Mutate(변형) state를 쓰지말고 새로운 state를 리턴해줘야한다. (불변성)
[...state, {text: text}]
{...state, ...newDate }
Object.assign({}, state, newDate)
combindReducer()
분리된 리듀서를 합쳐주는 함수
import { combineReducers } from "redux";
import postReducer from './post';
import userReducer from './user';
// 키가 initialState키가 되어야한다.
const reducer = combineReducers({
user: userReducer,
posts: postReducer
})
export default reducer;
// user.js
// state에는 초기값이 필요하다.
const userReducer = (state = null, action) => {
switch(action.type) {
case 'LOG_IN':
return action.data
case 'LOG_OUT':
return null
default:
return state;
}
}
export default userReducer;
redux-react
npm install react-redux
변화를 감지하려면 최상단 파일 index.js에서 provider로 감싸주고
store props내려준다.
import App from './App';
import React from 'react';
import ReactDom from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
ReactDom.render(
<Provider store={store}>
<App />
</Provider>
, document.getElementById('root'));
Connect()
components를 store에 연결시켜준다.
connect는
mapStateToProps(store state를 컴포넌트 props로 내려주는) ,
mapDispatchToProps(store dispatch를 컴포넌트 props로 내려주는)
2개의 argument를 가진다.
import { connect } from 'react-redux';
export default connect(mapStateToProps, mapStateToProps)(Home);
mapStateToProps만 필요한 컴포넌트의 경우
import { connect } from 'react-redux';
export default connect(mapStateToProps)(Home);
mapDispatchToProps만 필요한 컴포넌트의 경우
export default connect(null, mapDispatchToProps)(Home);
mapStateToProps
redux state로 부터 home(component)에 prop로 전달한다.
// Home.js
import { connect } from 'react-redux';
function Home({todos}){
return <div>{todos}</div>
}
// ownProps는 현재 컴포넌트에서 받고있는 props를 받을 수 있다.
function mapStateToProps(state, ownProps) {
return { todos: state }
}
export default connect(mapStateToProps)(Home);
mapDispatchToProps
redux dispatch를 home(component)에 props로 전달한다.
function Home({dispatch}) {
}
function mapDispatchToProps(dispatch, ownProps) {
return {dispatch};
}
export default connect(null, mapDispatchToProps)(Home);
userSelector(), useDispatch()
connect()함수를 사용하여 컴포넌트에 store를 연결시켜주었는데
useSelector, useDispatch hook을 사용하여 간편하게 사용할 수 있게 되었다.
import { useSelector, useDispatch } from 'react-redux';
const user = useSelector(state => state.user);
cosnt dispatch = useDispatch();
참고
'TECH' 카테고리의 다른 글
styled-components, emotion 비교 (0) | 2023.02.22 |
---|---|
redux-toolkit (0) | 2023.02.20 |
tsconfig.json 기본세팅, d.ts, JSDoc (0) | 2023.02.14 |
Typescript 기초개념 정리 (0) | 2023.02.14 |
async, await 알아보기 (0) | 2022.03.30 |