[22.06.29]

김도훈·2022년 6월 29일
0

Redux

개념

-JavaScript 상태관리 라이브러리

Node.js 모듈
상태관리 툴 종류: React Context, Redux, Mobx

상태관리 필요성

• 상태관리

React에서 State는 component 안에서 관리되는 것
• Component간의 정보 공유

자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능
자식 컴포넌트들 간의 데이터를 주고 받을 때는 상태를 관리하는 부모 컴포넌트를 통해서 주고 받음.
자식이 많아지면 상태 관리가 매우 복잡해짐.
상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야 함.
-> Props drilling 이슈
전역 상태 저장소가 있고, 어디서든 해당 저장소에 접근할 수 있다면 문제 해결

구성

• Provider란?

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

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

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

생성한 action 실행

사용

• npm install redux react-redux

react-redux: 리액트 환경에 맞는 리덕스를 사용할 수 있게 해줌

실습

App.js
import logo from './logo.svg';
import './App.css';
import {Container, Row, Col} from 'react-bootstrap';
import ContactForm from './components/ContactForm';
import ContactList from './components/ContactList';
import 'bootstrap/dist/css/bootstrap.min.css'

function App() {
return (

<div className="App">
  <h1 className = "title">연락처</h1>
  <Container>
    <Row>
      <Col>
        <ContactForm></ContactForm>
      </Col>
      <Col>
        <ContactList></ContactList>
      </Col>
    </Row>
    <Row></Row>
  </Container>
</div>

);
};

export default App;
ContactForm.js
import React from 'react';
import {Form, Button} from 'react-bootstrap';

const ContactForm = () => {
return(

<Form>
  <Form.Group className="mb-3" controlId="formName">
    <Form.Label>이름</Form.Label>
    <Form.Control type="text" placeholder="이름을 입력해주세요" />
</Form.Group>

  <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label>Password</Form.Label>
    <Form.Control type="password" placeholder="Password" />
  </Form.Group>
  <Form.Group className="mb-3" controlId="formBasicCheckbox">
    <Form.Check type="checkbox" label="Check me out" />
  </Form.Group>
<Button variant="primary" type="submit">
  Submit
</Button>
); }

export default ContactForm;
ContactItem.js
import React from 'react';
import {Row, Col} from 'react-bootstrap';

const ContactItem = () =>{
return(

  <Col lg = {1}>
    <img width = {50} src = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Unknown_person.jpg/542px-Unknown_person.jpg?20200423155822" alt = "" />
  </Col>
  <Col lg = {11}>
    <div></div>
    <div></div>
  </Col>
</Row>

);
}

export default ContactItem;
ContactList.js
import React from 'react';
import ContactItem from './ContactItem';
import SearchBox from './SearchBox';

const ContactList = () =>{
return(

<div>
  <SearchBox></SearchBox>
  <ContactItem></ContactItem>
</div>

);
}

export default ContactList;
ContactBox.js
import React from 'react';
import {Row, Col, Form, Button} from 'react-bootstrap';

const SearchBox = () =>{
return(

  <Col lg = {10}>
    <Form.Control type = "text" placeholder = "이름을 입력해주세요" />
  </Col>
  <Col lg = {2}>
    <Button>찾기</Button>
  </Col>
</Row>

);
}

export default SearchBox;
App.css
.title {
text-align: center;
}

Redux 연결

sotre.js 파일 생성
import {createStore} from 'redux';
import reducer from './reducer/reducer';

let store = createStore(reducer);
export default store;
reducer 폴더 생성 후 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;
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(



);

reportWebVitals();
ContactForm.js
import React, {useState} from 'react';
import {Form, Button} from 'react-bootstrap';
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>이름</Form.Label>
    <Form.Control type="text" placeholder="이름을 입력해주세요" 
    onChange = {(event) => setName(event.target.value)} />
</Form.Group>

  <Form.Group className="mb-3" controlId="formBasicPassword">
    <Form.Label>전화번호</Form.Label>
    <Form.Control type="number" placeholder="전화번호를 입력해주세요"
    onChange = {(event) => setPhoneNumber(event.target.value)} />
  </Form.Group>
  <Form.Group className="mb-3" controlId="formBasicCheckbox">
    <Form.Check type="checkbox" label="Check me out" />
  </Form.Group>
<Button variant="primary" type="submit">
  Submit
</Button>
); }

export default ContactForm;
ContactList.js
import React from 'react';
import { useSelector } from 'react-redux';
import ContactItem from './ContactItem';
import SearchBox from './SearchBox';

const ContactList = () =>{
const contactList = useSelector((state) => state.contactList);

return(

<div>
  <SearchBox/>
  {contactList.map((item) => (
  <ContactItem item = {item} />
  ))}
</div>

);
}

export default ContactList;
ContactItem.js
import React from 'react';
import {Row, Col} from 'react-bootstrap';

const ContactItem = ({item}) =>{
return(

  <Col lg = {1}>
    <img width = {50} src = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Unknown_person.jpg/542px-Unknown_person.jpg?20200423155822" alt = "" />
  </Col>
  <Col lg = {11}>
    <div>{item.name}</div>
    <div>{item.phoneNumber}</div>
  </Col>
</Row>

);
}

export default ContactItem;

0개의 댓글