[DAY40]_개발일지: React.js Redux

hanseungjune·2022년 6월 29일
0

DaeguFE

목록 보기
47/48

✅ Redux란?

  • JavaScript 상태관리 라이브러리
  • Node.js 모듈
  • 상태관리 툴 모듈 종류 중에 하나

☑️ Redux를 사용하는 이유

바로, 상태관리의 필요성 때문이다!

  • 상태관리
    - React에서 상태(state)는 component 안에서 관리되는 것
    • Component끼리 데이터 연결을 가능하게 하여 관리가 되는 것이다.

      ▶ 자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능
      ▶ 자식 컴포넌트들 간의 데이터를 주고 받을 때는 상태를 관리하는 부모
      컴포넌트를 통해서 주고 받는다
      ▶ 자식이 많아진다면 상태 관리가 매우 복잡해진다.
      ▶ 상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야한다.
      → Props drilling 이슈

그래서 전역상태 저장소가 필요하고, 어디서든 해당 저장소를 접근할 수 있게 하여야한다. 그래서 Redux를 사용하는 것이다.

☑️ Redux를 활용하기 위해서 필요한 것

Provider

  • Provider은 react-redux라이브러리 안에 있는 컴포넌트입니다
  • 리액트 앱에 스토어를 쉽게 연결하기 위한 컴포넌트 입니다.

combineReducer

  • redux모듈이 제공하는 함수이다.
  • 만든 모든 리듀서들을 통합하여 하나의 리듀서로 쓰기 위한 함수이다

useSelector

  • redux의 state조회 (즉, 스토어에 있는 데이터들 조회)

useDispatch

  • 생성한 action 실행

✅ 연락처 기록 및 저장UI 만들기

☑️ Redux 설치

npm install redux react-redux

☑️ UI부터 만들기

일단 최종적인 결과물부터 공개하겠다. ( 이유 : 사실 모든 코드를 이해 못해서 해석이 안됨 )


▶ 화면처럼 작동을 하기는 한다. 하핳

이번에 필요한 파일이 총 9개 정도 된다. 그래서 일단 미리 목록을 올려두려고 한다.

ContactForm.jsx
ContactItem.jsx
ContactList.jsx
SearchBox.jsx
reducer.js
App.css
App.js
store.js
index.js

ContactForm.jsx

import React, {useState} from "react";
import {Form, Button} from 'react-bootstrap';
import "bootstrap/dist/css/bootstrap.min.css";
import { useDispatch } from "react-redux";

const ContactForm = () => {
  const [name, setName] = useState('');
  const [phoneNumber, setPhoneNumber] = useState(0);
  const dispatch = useDispatch();

  const addContact = (event) => {
    event.preventDefault();
    dispatch({
      type: 'ADD_CONTACT',
      payload: { name, phoneNumber },
    });
  }

  return(
    <Form onSubmit={addContact}>
      <Form.Group className="mb-3" controlId="formName">
        <Form.Label>Your Name</Form.Label>
        <Form.Control 
          type="text" 
          placeholder="Enter Name" 
          onChange={(event) => setName(event.target.value)}
        />
      </Form.Group>
      <Form.Group className="mb-3" controlId="formContact">
        <Form.Label>Your PhoneNumber</Form.Label>
        <Form.Control 
          type="number" 
          placeholder="Enter PhoneNumber" 
          onChange={(event) => setPhoneNumber(event.target.value)}  
        />
      </Form.Group>
      <Button variant="primary" type="submit">
        Add
      </Button>
    </Form>
  );
}

export default ContactForm;

ContactList.jsx

import React from 'react';
import SearchBox from './SearchBox';
import "bootstrap/dist/css/bootstrap.min.css";
import ContactItem from './ContactItem';
import { useSelector } from 'react-redux';

const ContactList = () => {
  const contactList = useSelector((state) => state.contactList);
  return (
    <div>
      <SearchBox />
      {contactList.map((item) => (
        <ContactItem item={item} />
      ))}
    </div>
  );
};

export default ContactList;

SearchBox.jsx

import React from 'react';
import {Form, Button, Row, Col} from 'react-bootstrap';
import "bootstrap/dist/css/bootstrap.min.css";
import '../App.css';

const SearchBox = () => {
  return (
    <Row>
      <Col lg={10}>
        <Form.Label>Search Name</Form.Label>
        <Form.Control type="text" placeholder="이름을 입력해주세요" />
      </Col>
      <Col lg={2}>
        <Button id="search_btn">찾기</Button>
      </Col>
    </Row>
  );
};

export default SearchBox;

ContactItem.jsx

import '../App.css';
import React from 'react';
import { Row, Col } from 'react-bootstrap';

const ContactItem = ({ item }) => {
  return (
    <Row>
      <Col lg={1}>
        <img
          width={50}
          src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Unknown_person.jpg/925px-Unknown_person.jpg"
          alt=""
          id='img_unknown'
        />
      </Col>
      <Col lg={11} id='img_unknown'>
        <div>{item.name}</div>
        <div>{item.phoneNumber}</div>
      </Col>
    </Row>
  );
};

export default ContactItem;

여기까지 컴포넌트를 완성하여 App.js에 데이터를 모아주고 index.js에 연결하여 UI로 나타나게 해준다.

App.js

import './App.css';
import React from 'react';
import {Container, Row, Col} from 'react-bootstrap';
import ContactForm from './components/ContactForm';
import ContactList from './components/ContactList';

function App() {
  return (
    <div className="App">
      <h1 className="title">연락처</h1>
      <Container>
        <Row>
          <Col>
            <ContactForm></ContactForm>
          </Col>
          <Col>
            <ContactList></ContactList>
          </Col>
        </Row>
      </Container>
    </div>
  );
}

export default App;

App.css

.title {
  text-align: center;
  /* border-top: 1px solid blue;
  border-bottom: 1px solid blue; */
}

#search_btn { 
  margin-top: 32px;
  margin-bottom: 32px;
}

#img_unknown {
  margin-top: 10px;
  margin-bottom: 10px;
}

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './store';
import {Provider} from 'react-redux';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

// 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();

위의 4개의 컴포넌트를 App.jsindex.js 순으로 거쳐서 UI를 생성

reducer.js

let initialState = {
  contactList: [],
};

function reducer(state = initialState, action) {
  const { type, payload } = action;
  switch (type) {
    case 'ADD_CONTACT':
      return {
        ...state,
        contactList: [
          ...state.contactList,
          {
            name: action.payload.name,
            phoneNumber: action.payload.phoneNumber,
          },
        ],
      };
    default:
      return { ...state };
  }
}

export default reducer;

store.js

import {createStore} from 'redux';
import reducer from './reducer/reducer';

let store = createStore(reducer);

export default store;

UI에서 Action을 요청하면, 이를 reducer를 거쳐서, store로 값이 저장된다. 그리고 이를 UI로 다시 보내주는 과정을 거치면, 아까처럼 입력하고 바로 화면에 값이 저장되는 결과를 낳게 한다.

사실 진도를 나가기 바빠서 코드에 대한 설명을 해주시지 않았는데, 역시나 한번 React에 대한 간을 본다는 의미로 생각하고 개인적으로 공부를 해야하는게 아닐까하는 생각이 들었다.

profile
필요하다면 공부하는 개발자, 한승준

0개의 댓글