JavaScript 상태 관리 라이브러리이며 Node.js모듈이다.
상태관리란?
상태관리의 필요성
-자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능
-자식 컴포넌트들 간의 데이터를 주고 받을 때는 상태를 관리하는 부모 컴포넌트를 통해서 주고 받는다.
-자식이 많아진다면 상태 관리가 매우 복잡해진다.
-상태를 관리하는 상위 컴포넌트에서 계속 내려 받아야한다.
=> Props drilling 이슈
Provider란?
Provider는 react-redux라이브러리 안에 있고, 리액트 앱에 스토어를 쉽게 연결하기 위한 컴포넌트다.
•combineReducer란?
redux모듈이 제공하고, 만든 모든 리듀서들을 통합하여 하나의 리듀서로 쓰기 위한 함수다.
•useSelector란?
redux의 state조회(즉, 스토어에 있는 데이터들 조회)
•useDispatch란?
-생성한 action 실행
리덕스 설치
npm install redux react-redux
App.js
import logo from './logo.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
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;
components/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="formContact">
<Form.Label>전화번호</Form.Label>
<Form.Control
type="number"
placeholder="전화번호를 입력해주세요"
onChange={(event) => setPhoneNumber(event.target.value)}
/>
</Form.Group>
<Button variant="primary" type="submit">
추가
</Button>
</Form>
);
};
export default ContactForm;
components/ContactItem.js
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=""
/>
</Col>
<Col lg={11}>
<div>{item.name}</div>
<div>{item.phoneNumber}</div>
</Col>
</Row>
);
};
export default ContactItem;
components/ContactList.js
import React from 'react';
import SearchBox from './SearchBox';
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;
components/SearchBox.js
import React from 'react';
import { Row, Col, Form, Button } from 'react-bootstrap';
const SearchBox = () => {
return (
<Row>
<Col lg={10}>
<Form.Control type="text" placeholder="이름을 입력해주세요" />
</Col>
<Col lg={2}>
<Button>찾기</Button>
</Col>
</Row>
);
};
export default SearchBox;
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;
실행 결과
X
X
리덕스를 이용해 상태관리를 해야하는 이유와 간단한 코드를 구현해보니 어제나 그저께 했던 의문이 조금 풀리는 기분이었다. 하나하나 따로 작성하여 그것이 복잡하니 관리하는 것이 필요하다는 것이고 전역 저장소로 처리하는 방식 등이다.