1) 필기 내용
리덕스 : 자바스크립트 상태관리 라이브러리, Node.js 모듈
상태관리 종류 : React Context / Redux / Mobx
상태관리 :
자식 컴포넌트들 간의 다이렉트 데이터 전달은 불가능 → props 같은 것을 통해서 가능
자식 컴포넌트들 간의 데이터를 주고 받을 때 상태를 관리하는 부모 컴포넌트를 통해 주고 받음
자식이 많아지면 복잡
→ 이러한 상태들을 관리하는 라이브러리 중 리덕스!
상태관리의 필요성
모든 컴포넌트에서 접근이 가능한 전역 상태 저장소(STORE)가 있으면 문제 해결
리덕스의 구조 : ACTION → REDUCER → STORE → UI → ACTION
리덕스에 필요한 컴포넌트
1) Provider : STORE에 접근하기 위함
2) combinerReducer : REDUCER들이 여러 개일 때 통합하기 위한 함수
3) useSelector : STORE 데이터 조회
3) useDispatch : 생성한 action 실행
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
cd projcontact
npm install redux react-redux
→ redux와 react-redux 한꺼번에 설치
reaxt-redux : 리액트 환경에 맞는 리덕스를 사용할 수 있게 해줌
react-bootstrap 설치
https://react-bootstrap.github.io/ → Get started 선택 → npm install react-bootstrap bootstrap을 terminal에 입력
<Col lg={10}>
→ 비율을 10으로 하겠다~
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
과제는 아닌 숙제 아닌 Homework?
https://openweathermap.org/api 에서 회원가입하기
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
projcontact/src/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="text" placeholder="전화번호를 입력해주세요"
onchange={(event) => setPhoneNumber(event.target.value)} />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
);
}
export default ContactForm;
projcontact/src/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=""></img>
</Col>
<Col lg={11}>
<div>{item.name}</div>
<div>{item.phonNumber}</div>
</Col>
</Row>
);
}
export default ContactItem;
projcontact/src/components/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></SearchBox>
{contactList.map((item) => (
<ContactItem item={item} />
))}
</div>
);
}
export default ContactList;
projcontact/src/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;
projcontact/src/redecer/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.phonNumber,
}]
}
default :
return {...state};
}
}
export default reducer;
projcontact/src/App.js
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>
<Col>
</Col>
</Row>
</Container>
</div>
);
}
export default App;
projcontact/src/App.css
.title{
text-align: center;
}
projcontact/src/index.html
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();
projcontact/src/store.js
import {createStore} from 'redux';
import reducer from './reducer/reducer';
let store = createStore(reducer);
export default store;
→ 결과(아래 그림)
1) 지금도, 아직도, 강사님께서 보내주신 파일과 다른 바를 못찾고 있다...
2) 나는 왜 아직도 안될까?
1) 지금 비교 체험 중 ^~^
1) 오늘 좀 복잡했다... 진도가 막 빠르지는 않았는데... 컴포넌트들을 효율적으로 관리하기 위해 상태관리 중, Redux를 설치하고 사용한 것은 알겠는데, 그 이후, 헷갈려...