본문 바로가기
React를 같이 배워보자

React20일차-Redux를 react와 연결

by 멈추지않아 2022. 2. 9.

저번에 했던 폴더를 열고 코드 열고 npm start

index.js를

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./redux/store";

ReactDOM.render(
  <React.StrictMode>
    <App store={store} />
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

이렇게 변경

store을 props로 전달 해주었다.

App.js를

import logo from "./logo.svg";
import "./App.css";
import { useEffect, useState } from "react";
import { add } from "./redux/action";

function App({ store }) {
  const [state, setState] = useState(store.getState());
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setState({ ...store.getState() });
    });
    return () => {
      unsubscribe();
    };
  }, [store]);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        {JSON.stringify(state)}
        <button onClick={click}>추가</button>
      </header>
    </div>
  );
  function click() {
    store.dispatch(add(5));
  }
}

export default App;

이렇게 작성

여기서 주의할점은

setState({ ...store.getState() });
따로 공부하면서 알아낸것인데 배열은 그냥 store.getState()하면 변경이 됬지만 변경안된걸로 인식되어서
re-rendering이 안된다. 이점을 주의하자

useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setState({ ...store.getState() });
    });
    return () => {
      unsubscribe();
    };
  }, [store]);

이부분은을 설명 하겠다.

const unsubscribe = store.subscribe(() => {
      setState({ ...store.getState() });
    });

이거는 실행할때 실행된다.

  return () => {
      unsubscribe();
    };

이거는  unmount될때 실행된다.

즉 마운트되있을때는 데이터가 변경될때마다 state값을 최신화 시켜주고 unmount되면 그것을 멈추겠다라는 의미이다.

버튼이 클릭이될때마다  화면에 최신 값이 표시가 되는거다

클릭전
클릭후

이번에는 context를 이용해서 한번 전달 해보겠습니다

src/context 폴더만들고 그안에 ReduxContext.js파일 생성

import { createContext } from "react";

const store = createContext();

export default store;

작성

index.js이동

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import store from "./redux/store";

import ReduxContext from "./context/ReduxContext";

ReactDOM.render(
  <React.StrictMode>
    <ReduxContext.Provider value={store}>
      <App />
    </ReduxContext.Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
수정

app.js

import logo from "./logo.svg";
import "./App.css";
import { useContext, useEffect, useState } from "react";
import { add } from "./redux/action";
import ReduxContext from "./context/ReduxContext";
function App() {
  const store = useContext(ReduxContext);
  const [state, setState] = useState(store.getState());
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setState({ ...store.getState() });
    });
    return () => {
      unsubscribe();
    };
  }, [store]);
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        {JSON.stringify(state)}
        <button onClick={click}>추가</button>
      </header>
    </div>
  );
  function click() {
    store.dispatch(add(5));
  }
}

export default App;

수정

이렇게 보면 store를 {}이렇게 직접적이 props가 아니라 import해서 store라는 변수에 데이터를 저장해줌으로 써 사용하고 있다

작동도 잘되는것을 볼수 있다

이제 이렇게 만든것들을 hook으로 만들어서 처리 해보겠습니다.

src/hook폴더 만들고 addstore.js liststore.js 파일 생성

addstore.js

import { useContext } from "react";
import ReduxContext from "../context/ReduxContext";
export default function Liststore() {
  const store = useContext(ReduxContext);

  return store.dispatch;
}

store의 dispatch를 전달하여 사용할수 있도록 해주는 것입니다.

liststore.js

import { useContext, useEffect, useState } from "react";
import ReduxContext from "../context/ReduxContext";
export default function Liststore() {
  const store = useContext(ReduxContext);
  const [state, setState] = useState(store.getState());
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      setState({ ...store.getState() });
    });
    return () => {
      unsubscribe();
    };
  }, [store]);

 

  return state;
}

 

이렇게 수정하시고

state에 데이터를 저장하고 데이터 변경시 할 처리들도 함께 해주고 state만 전달 합니다.

App.js

import logo from "./logo.svg";
import "./App.css";

import { add } from "./redux/action";
import addstore from "./hook/addstore";
import liststore from "./hook/liststore";
function App() {
  const state = liststore();
  const dispatch = addstore();
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        {JSON.stringify(state)}
        <button onClick={click}>추가</button>
      </header>
    </div>
  );
  function click() {
    dispatch(add(5));
  }
}

export default App;

이렇게 수정

liststore에서 state를 받아와서 출력하고 

dispatch에 store.dispatch를 받아와서 데이터 추가를 수행할수 잇도록 해주고 잇습니다.

이렇게해서 데이터가 많이 짧아지게 되었습니다.