리덕스(REDUX)?
상태관리의 필요성

리덕스
Provider?
Provider는 react-redux라이브러리 안에 있는 컴포넌트
리액트 앱에 스토어를 쉽게 연결하기 위한 컴포넌트
combineReducer?
redux모듈이 제공하는 함수
만든 모든 리듀서들을 통합하여 하나의 리듀서로 쓰기 위한 함수
useSelector?
redux의 state 조회(스토어에 있는 데이터들 조회)
useDispatch?
생성한 action 실행
npm install redux react-redux
react-redux : 리액트 환경에 맞는 리덕스를 사용할 수 있게 해줌

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.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;
-화면 중앙에 연락처 글씨 만들기
-Form, List로 나눌 두 개의 컨테이너 생성
-부트스트랩, 컴포넌트 임포트해주기
2.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;
-화면 왼쪽 부분에 들어갈 2개 폼박스 박들기
-스토어, 리듀서 만든 후 리스트에 이름과 전화번호 값을 보낼 수 있도록
함수 useState,useDispatch 사용, 리액트-리덕스 임포트
-다시 리턴 부분에 event 함수 사용해서 값을 리스트로 보낼 수 있도록 해줌
-useState()함수 : 함수형 컴포넌트에서 상태를 관리
-import React,{useState}from 'react';로 함수 불러오기
-const [number,setNumber]=useState(0);
=> 1번째 원소 number는 현재 상태값 변수, 2번째 setNumber는 상태 값을 갱신해주는 Setter함수, useState 괄호 안의 값을 상태의 초기 값
const[상태 값 저장변수, 상태 값 갱신 함수] = useState(상태 초기 값)
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;
-useSelector 함수 사용
-map(item) 사용
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;
-리스트에 이미지 적용
-이름, 전화번호 값 받아서 적용
-부트스트랩 함수 사용해서 화면 사용 크기 적용
import React from "react";
import {Row, Col, Form, Button} from 'react-bootstrap';
const SearchBox = () => {
return(
<Row>
<Col lg={10}>
<Form.Label>검색</Form.Label>
<Form.Control type="text" placeholder="이름을 입력해주세요."/>
</Col>
<Col lg={2} className="Search">
<Button variant="primary" type="submit">
찾기
</Button>
</Col>
</Row>
);
}
export default SearchBox;
-오른쪽 리스트 받아올 부분의 창 생성
-이후 받아온 리스트 중 검색할 수 있는 버튼 생성
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();
-Provider 함수 사용해서 리듀서 사용 준비
import {createStore} from 'redux';
import reducer from './reducer/reducer';
let store = createStore(reducer);
export default store;
-스토어 만들어주기
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;
-initialState 함수 사용, 리스트 값 중개
-reducer함수 : 현재 상태와 액션 객체를 파라미터로 받아와서 새로운 상태를 반환
기본형태
fuction reducer(state,action){...}
state = 현재 상태
action = 업데이트와 관련된 정보를 가진 객체
return = 업데이트 될 값
dispatch = action을 발생시키는 함수
switch문을 사용해서 action 객체에 담긴 type에 따라 상태 업데이트 로직을 작성
initialState : 초기 상태
리액트를 사용하면서 나오는 문법적인 부분들이 아직 생소하고 어렵다. 왜, 어떻게, 사용되어야 하는지 다른 예들을 찾아볼 필요가 있다. 그리고 검색부분은 아직 완성시키질 못했는데 따로 찾아보고 원래 목표로 했던 코인 홈페이지 만들기라는 부분도 공부 할 수 있는 부분을 찾아봐야겠다.
파이썬과 관련된 책을 오늘 선물 받았다. 가장 기초적인 부분을 다루고 있지만 시간이 지난만큼 새로 찾아보기도 하고 익숙해질 필요가 있다. 리액트 부분들도 문법적인 부분들을 어떻게 사용해야 하는지 좀 더 익숙해질 수 있도록 다양하게 찾아봐야겠다.
어떤 도구든 문법적인 부분이 가장 어렵고 어떻게 적용시켜야할지 감이 잡히지를 않는다. 그저 많이 사용하다보면 감이 온다는데..이건 누가 도와줄 수 있는 부분이 아니라 그저 내가 열심히 하는 수 밖에 없다. 뭐든 하다보면 익숙해진다. 나도 감이 오는 그 날까지, 최대한 해보자.