본문 바로가기
개발(라이브러리,프레임워크)/react.js & react native

Redux 를 React에 연결(라이브러리x)

by zieunee 2022. 1. 21.
반응형

react-redux 라이브러리 안쓰고 연결하기

단일 store을 만들고 subscribe 와 getState를 이용하여 변경되는 state데이터를 얻어 props로 계속 아래로 전달하기

componentDidMount > subscribe

componenWillUnMount > unsubscribe

index.js

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

store를 props로 내려준다.

App.js

import logo from './logo.svg';
import './App.css';
import { useEffect, useState } from 'react';
import { addTodo } from './redux/actions';

function App({store}) {
  const [state, setState] = useState(store.getState); //초기값 store.getState 로 지정 
  useEffect(() => {
    console.log("useEffect");
    const unsubscribe =  store.subscribe(()=>{
      console.log("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(addTodo('todo'));
  }
}

export default App;

props로 들어오는 store 가 수정되었을때 useEffect 실행된다.

app.js내에서 store가 수정되었을때 subscribe가 실행되어 state 값을 변경해준다.

click을 할 때 마다 subscribe 가 실행된다.

store를 전체 컴포넌트에 전달하는 방법

context 사용

index.js

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

Provider 를 사용할 경우에 props로 value값만 넣을 수 있음

앱 하위에 있는 모든 컴포넌트들은 store를 꺼내서 쓸 수 있다.

ReduxContext

import { createContext } from "react";

const ReduxContext = createContext();

export default ReduxContext;

App.js

import logo from './logo.svg';
import './App.css';
import { useEffect, useState, useContext } from 'react';
import { addTodo } from './redux/actions';
import ReduxContext from './contexts/ReduxContext';

function useReduxState(){
  //store 가져오는 훅 생성
  const store = useContext(ReduxContext);
  const [state, setState] = useState(store.getState); //초기값 store.getState 로 지정 

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

  return state;
}

function useReduxDispatch(){
  //dispatch를 가져오는 훅 
  const store = useContext(ReduxContext); 
  return store.dispatch;
}

function App() {
  const state = useReduxState(); 
  const dispatch = useReduxDispatch();
  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(addTodo('todo'));
  }
}

export default App;

useReduxState 훅 : context로 부터 store를 가져오고 store로 부터 getState해서 업데이트가 일어날때바다 setstate해서 state를 리턴해준다.

useReduxDispatch 훅: dispatch를 사용할수 있다.

기능별로 나누기

App.js :랜더

import logo from './logo.svg';
import './App.css';
import { addTodo } from './redux/actions';
import TodoList from './components/TodoList'
import TodoForm from './components/TodoForm'

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
          <TodoList />
          <TodoForm />
      </header>
    </div>
  );
}

export default App;

TodoList.jsx state를 보여줌

import useReduxState from "../hooks/useReduxState";

export default function TodoList(){
    const state = useReduxState();
    return <ul>
    {state.todos.map((todo)=>{
        return <li>{todo.text}</li>;
    })}
    </ul>
}

TodoForm.jsx state를 추가한다.

import { useRef } from "react";
import useReduxDispatch from "../hooks/useReduxDispatch";
import { addTodo } from "../redux/actions";
export default function TodoForm(){
   const inputRef = useRef();
   const dispatch = useReduxDispatch();
   return (
    <div>
        <input ref = {inputRef} />
        <button onClick={click}>추가</button>
    </div>
    );
    function click(){
        dispatch(addTodo(inputRef.current.value));
    }
}

useReduxState.js state를 바꿔준다.

import { useContext, useEffect, useState } from "react";
import ReduxContext from "../contexts/ReduxContext";

export default function useReduxState(){
    //훅 생성
    const store = useContext(ReduxContext);
    const [state, setState] = useState(store.getState); //초기값 store.getState 로 지정 

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

    return state;
  }

useReduxDispatch.js dispatch기능

import { useContext } from "react";
import ReduxContext from "../contexts/ReduxContext";

export default function useReduxDispatch(){
    //dispatch를 가져오는 훅 
    const store = useContext(ReduxContext);

    return store.dispatch;
  }
반응형

'개발(라이브러리,프레임워크) > react.js & react native' 카테고리의 다른 글

리덕스 미들웨어  (0) 2022.02.01
Async Action  (0) 2022.01.31
Redux 개요, 사용  (0) 2022.01.20
Hooks  (0) 2022.01.09
라우팅  (0) 2021.09.26