Node.js ๋ชจ๋
์ํ๊ด๋ฆฌ ํด ์ข
๋ฅ: React Context, Redux, Mobx
-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
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;
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>
</Form>
);
}
export default ContactForm;
import React from 'react';
import {Row, Col} from 'react-bootstrap';
const ContactItem = () =>{
return(
<Row>
<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;
import React from 'react';
import ContactItem from './ContactItem';
import SearchBox from './SearchBox';
const ContactList = () =>{
return(
<div>
<SearchBox></SearchBox>
<ContactItem></ContactItem>
</div>
);
}
export default ContactList;
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;
.title {
text-align: center;
}
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;
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>
);
reportWebVitals();
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>
</Form>
);
}
export default ContactForm;
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;
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/542px-Unknown_person.jpg?20200423155822" alt = "" />
</Col>
<Col lg = {11}>
<div>{item.name}</div>
<div>{item.phoneNumber}</div>
</Col>
</Row>
);
}
export default ContactItem;
๋ฆฌ์ํธ ๊ด๋ จ๋ ๋ฌธ๋ฒ ๊ณต๋ถ๊ฐ ํ์ํ๊ฒ ๊ฐ๋ค.