[스터디] #11 react redux, redux toolkit

ch9eri·2022년 11월 11일
0

멋사 프론트 스터디

목록 보기
11/12

Provider

Provider컴포넌트를 통해 앱의 다른 컴포넌트에서 Redux store를 사용할 수 있다

import { Provider } from 'react-redux'
import store from './store'
//index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
    <App />
</Provider>
);

connect()

import { connect } from 'react-redux';

💡 argument로 state, dispatch를 가짐
state: Redux store에서 온 state
dispatch: component의 props

connect()는 return한 것을 component의 prop에 추가해준다.

mapStateToProps

두 종류의 argument와 함께 호출되는 함수

function mapStateToProps(state, ownProps)

function mapStateToProps(state) {
  return { toDos: state };
}

export default connect(mapStateToProps)(Home);
<ul>{JSON.stringify(toDos)}</ul>

→ toDos 상태

function mapDispatchToProps(dispatch) {
    return {
      addToDo: text => dispatch(actionCreators.addToDo(text))
    };
  }

-> component로부터 reducer에게 dispatch하기

function mapStateToProps(state) {
  return { toDos: state };
}

function mapDispatchToProps(dispatch) {
    return {
      addToDo: text => dispatch(actionCreators.addToDo(text))
    };
  }
  
export default connect(mapStateToProps, mapDispatchToProps)(Home);

-> 컴포넌트가 직접 dispatch나 actionCreators 할 필요 없이 두개의 함수를 만든다

+ useDispatch()

Redux store에서 dispatch 함수에 대한 참조를 반환
(mapDispatchToProps대신 사용 가능)


import { useDispatch } from 'react-redux'

const dispatch = useDispatch()

dispatch(addTodo(text));

mapDispatchToProps대신 useDispatch() 사용해서 dispatch하기


const dispatch = useDispatch();

const onClick = () => {

dispatch(deleteTodo(id));

};

< button onClick={onClick} >❌< /button >

delete

function ToDo({ text, onBtnClick }) {
  return (
    <li>
      {text} <button onClick={onBtnClick}>DEL</button>
    </li>
  );
}

function mapDispatchToProps(dispatch, ownProps) {
  return {
    onBtnClick: () => dispatch(actionCreators.deleteToDo(ownProps.id)),
  };
}
const dispatch = useDispatch();

const onClick = () => {
	dispatch(deleteTodo(id));
};

< button onClick={onClick} >DEL< /button >

-> useDispatch를 사용하면 더 간단해진다


? 마크

자바스크립트에서 지원하는 Optional Chaining 기능

function Detail({ toDos }) {
  const myId = useParams().id;
  const toDo = toDos.find((toDo) => toDo.id === parseInt(myId));

  return (
    <>
      <h1>{toDo?.text}</h1>
      <h5>Created at: {toDo?.id}</h5>
    </>
  );
}

props에 빈객체가 나와서 useParams사용했다

const myId = useParams().id;
const toDo = toDos.find((toDo) => toDo.id === parseInt(myId));

find()를 사용해 id가 같은 것 찾아냄


redux toolkit

적은 양의 코드로 같은 기능 하기

createAction

Redux action type 및 creator를 정의하기 위한 helper 함수

import { createAction } from "@reduxjs/toolkit";

-> import

const ADD = "ADD";

const addToDo = text => {
	return {
	type: ADD,
	text
	};
};

이 코드를

const addToDo = createAction("ADD");

이렇게 줄일 수 있다 → 예전과 달리 action을 정의하지 않아도 됨

action은 type(string)과 payload를 갖는다
(내가 어떠한 정보를 보내든 payload와 함께 보내짐)

createReducer

const reducer = (state = [], action) => {
  switch (action.type) {  
    case addToDo.type:
      return [{ text: action.payload, id: Date.now() }, ...state];
    case deleteToDo.type:
      return state.filter(toDo => toDo.id !== action.payload);
    default:
      return state;
  }
};

이 코드를 → state를 mutate 하지 못함 → 새로운 state 생성

const reducer = createReducer([], {
  [addToDo]: (state, action) => {
    state.push({ text: action.payload, id: Date.now() });
  },
  [deleteToDo]: (state, action) =>
    state.filter(toDo => toDo.id !== action.payload)
});

이렇게 줄일 수 있다 → state mutate 가능


configureStore

store 설정에 몇몇 기본 값을 추가

  • state를 볼 수 있다 (type, payload)
  • 언제 어떤 action이 발생했는지 알 수 있다
  • dispatcher 사용
const store = configureStore({ reducer });

createSlice

reducer뿐만 아니라 action도 생성해줌

초기 state, reducer 함수의 객체, "slice 이름"을 받아 리듀서 및 state에 해당하는 action crator와 action type을 자동으로 생성하는 함수

const addToDo = createAction("ADD");
const deleteToDo = createAction("DELETE");

const reducer = createReducer([], {
  [addToDo]: (state, action) => {
    state.push({ text: action.payload, id: Date.now() });
  },
  [deleteToDo]: (state, action) =>
    state.filter(toDo => toDo.id !== action.payload)
});

이 코드를

const toDos = createSlice({
  name: "toDosReducer",
  initialState: [],
  reducers: {
    add: (state, action) => {
      state.push({ text: action.payload, id: Date.now() });
    },
    remove: (state, action) => state.filter(toDo => toDo.id !== action.payload)
  }
});

요런식으로 줄여서 사용할 수 있다

profile
잘하자!

0개의 댓글