๐ก Redux
redux๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ state ๋ฅผ ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๊ณ ๊ด๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ store ๋ฅผ ํตํด ์ฌ๋ฌ ์ปดํฌ๋ํธ์ ์ฝ๊ฒ ์ ๋ฌํ๊ณ ๊ด๋ฆฌํ ์ ์๋๋ก ๋ง๋ ๋ค. ์ฆ Flux ์ ๊ฐ์ ๊ตฌ์กฐ์ด๋ค.
React ์์ ํ๊ฒฝ์์ Redux ์ฌ์ฉํ๊ธฐ (๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น)
npm install --save redux
npm install --save react-redux
npm install --save redux-actions
๐ก ํ๋ฆ : VIEW -> ACTION -> (STORE) -> REDUCER -> DISPATCH(ACTION) -> STATE -> UI
index.js ์์ฑ
store ๋ฅผ ์์ฑํ๊ณ store ๋ฅผ <Provider>์ props ๋ก ์ ๋ฌํด์ ์ปดํฌ๋ํธ ํธ๋ฆฌ์ ์ ๊ทผํ ์ ์๋๋ก ๋ง๋ ๋ค. ๊ทธ๋ฆฌ๊ณ App.js ์์ reducers ๋ฅผ ์ํฌํธํ๋ค.
App.js ์์ ๋ฉ์ธ ์ฝ๋ ์์ฑ
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import {createAction, handleActions} from 'redux-actions';
class App extends Component {
render() {
return (
<div>
<h1>Redux ํ
์คํธ</h1>
<h1>{this.props.result}</h1>
<button onClick={this.props.onInc}>๋ํ๊ธฐ</button>
<button onClick={this.props.onDec}>๋นผ๊ธฐ</button>
</div>
);
}
}
๐ก Store
๋ชจ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ state๋ store์ ์ ์ฅ๋๋ฉฐ, redux์ ๋ชจ๋ ๊ฒ์ ์ด๊ดํ๋ค.
state ํจ์ ์์ฑ Store ์์ state๋ฅผ ๊บผ๋ด ๋ฐํํ๋ค.
// App: ์ด์ ๊ฐ๊ณผ ๋ณ๊ฒฝ๊ฐ์ด ๋์ผํ๋ฉด App ์ผ๋ก ์๊ฐ๋ค.
const stateToProps = state => {
console.log('stateToProps', state.num);
return { result: state.num };
}
๐ก Dispatch
state๋ฅผ ๋ฐ๊พธ๊ธฐ ์ํด์ store์ ์ ํธ๋ฅผ ๋ณด๋ด๋ฉด ๋๋๋ฐ ์ด ์ ํธ๊ฐ action ์ด๋ค. dispatch ๋ฅผ ํตํด action ์ ๋ฐ์์ํจ๋ค. dispatch ์ action ์ ๋ฃ์ด์ฃผ์ง ์์ผ๋ฉด ( => dispatch(action) ) reducer ๊ฐ ๋์ํ์ง ์๋๋ค.
dispatch ๋์ : action์ action creater ๊ฐ ๋ง๋ค์ด์ฃผ๊ณ action creater ๋ฅผ ๋ด์ dispatcher ์ด์ฐจ๊ฐ ์คํ๋๋ฉด ํด๋น action ์ ๋ํ reducer ๊ฐ ์คํ๋๋ค.
const INC = 'INC'
const DEC = 'DEC'
const inc = createAction(INC);
const dec = createAction(DEC);
const dispatchToProps = dispatch => bindActionCreators({
// action ์ ๋ด๊ณ reducer ๋ก ํฅํ๋ dispatch ์ด์ฐจ
onInc: inc,
onDec: dec
}, dispatch)
๐ก Reducer (Store ์ Reducer)
Store ์ state ์ action ์ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์์, ํด๋น action ์ ๋ง๋ ์์ ์ ํ์ฌ state ๋ฅผ ๋ณ๊ฒฝํ๋ค. ์ด์ state ์ action ์ ํตํด์ ์๋ก์ด state ์์ฑํ๋ค.
Reducer ์์ Store ๋ก ๋ณ๊ฒฝ๋ state ๊ฐ์ด ๋ฐํ๋๊ณ ์ ์ฅ๋๋ค.
const initState = {
num: 100
}
// dispatcher ๊ฐ ์ ๋ฌํ action ์ ํ์
์ ๋ณด๊ณ ๊ทธ์ ๋ง๋ ํ๋์ ํ๋ค.
export const reducers = handleActions({
[INC]: (state, action) => ({num: state.num+1}),
[DEC]: (state, action) => ({num: state.num-1})
}, initState);
// reducer ์์ store ๋ก ๊ฐ์ด ๋ฐํ๋๋ค.
// ๋ณ๊ฒฝ๋๋ num ๊ฐ์ด store ์ ์ ์ฅ๋๋ค.
๐ก state ์ dispatch connect ํ๊ณ export ํ๊ธฐ
connect : State - Dispatch - App
createStore : Store - Reducer
connect : React ์ปจํ ์ด๋๋ฅผ Redux ์ ๋ฐ์ธ๋ฉํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
export default App = connect(
stateToProps,
dispatchToProps
)(App)
์น ์คํ ํ๋ฉด
๐ก ์๋ก์ด ์ปดํฌ๋ํธ ์คํํ๊ธฐ (Bpp)
๐ฅ Listener ์ด๋?
Store ์์ ์๋ state (์ํ) ๊ฐ ๋ฐ๋ ๋ ๋ง๋ค ํธ์ถ๋๋ ํจ์์ด๋ค.
๐ฅ subscribe ์ด๋?
dispatch ๊ฐ ์คํ๋ ๋๋ง๋ค subscribe ์ ์ ๋ฌํ ํจ์๊ฐ ํธ์ถ๋๋ค.
index.js ์์ listener ์ subscribe ํจ์ ์์ฑํ๊ธฐ
const store = createStore(reducers)
const listener = () => {
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
}
store.subscribe(listener)
listener()
reportWebVitals();
App.js ์์ฑํ๊ธฐ
import React, { Component } from 'react'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'
import { createAction, handleActions } from 'redux-actions'
class App extends Component {
render() {
return (
<ConnectBpp/>
);
}
}
class Bpp extends Component{
render(){
return(
<div>
<h1>{this.props.result}</h1>
<button onClick={this.props.onINC}>๋ํ๊ธฐ</button>
<button onClick={this.props.onDEC}>๋นผ๊ธฐ</button>
</div>
)
}
}
const stateToProps = state => {
console.log('stateProps', state.num)
return { result: state.num}
}
const INC = 'INC'
const DEC = 'DEC'
const inc = createAction(INC)
const dec = createAction(DEC)
const dispatchToProps = dispatch => bindActionCreators({
onINC: inc,
onDEC: dec
}, dispatch, console.log('dispatcher'))
const initState = { num: 300 }
export const reducers = handleActions({
[INC]: (state, action) => ( { num: state.num + 1 }),
[DEC]: (state, action) => ({ num: state.num - 1 })
}, initState)
const ConnectBpp = connect(
stateToProps,
dispatchToProps
)(Bpp)
export default App
๐ก connect ๋์ Hook ์ฌ์ฉํ๊ธฐ
๐ฅ Hook ์ด๋?
ํจ์ํ ์ปดํฌ๋ํธ์์ ์ํ๊ฐ ๋ณํ ๋ Hook ์ ์ฌ์ฉํ์ฌ ์ํ ๊ด๋ฆฌ๋ฅผ ํ๋ค.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App, {reducers} from './App';
import reportWebVitals from './reportWebVitals';
import {Provider} from 'react-redux'
import {createStore} from 'redux'
const store = createStore(reducers)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
reportWebVitals();
import React, { Component } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createAction, handleActions } from 'redux-actions';
class App extends Component {
render() {
return (
<div>
<ConnectBpp />,
<ConnectCpp />,
<Dpp />
</div>
);
}
}
class Cpp extends Component {
render() {
return (
<div>
<h1>ํ์ธ : {this.props.result}</h1>
</div>
);
}
}
class Dpp extends Component {
render() {
return (
<ConnectBpp />
);
}
}
class Bpp extends Component {
render() {
return (
<div>
<h1>Redux ํ
์คํธ</h1>
<h1>{this.props.result}</h1>
<button onClick={this.props.onINC}>๋ํ๊ธฐ</button>
<button onClick={this.props.onDEC}>๋นผ๊ธฐ</button>
</div>
);
}
}
const INC = 'INC'
const DEC = 'DEC'
const inc = createAction(INC);
const dec = createAction(DEC);
const initState = {
num: 100
}
export const reducers = handleActions({
[INC]: (state, action) => ({ num: state.num + 1 }),
[DEC]: (state, action) => ({ num: state.num - 1 })
}, initState);
const ConnectBpp = () => {
const num = useSelector(state => state.num)
const dispatch = useDispatch()
return (
<Bpp result={num}
onINC={() => dispatch(inc())}
onDEC={() => dispatch(dec())}
/>
)
}
const ConnectCpp = () => {
const num = useSelector(state => state.num)
return (
<Cpp result={num} />
)
}
export default App
useSelector : connect ๋ฅผ ์ฌ์ฉํ์ง ์๊ณ redux ์ state ์ ์ ๊ทผํ ์ ์๋ค.
useDispatch : ์์ฑํ action ์ useDispatch ํจ์๋ฅผ ํตํด ๋ฐ์์ํฌ ์ ์๋ค.
์น ์คํ ํ๋ฉด
'JavaScript > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[React] ๊ธ์ฐ๊ธฐ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ (0) | 2021.10.22 |
---|---|
[React] Redux ํด๋ ๊ตฌ์กฐ ์ ๋ฆฌํ๊ธฐ (0) | 2021.10.21 |
[React] React ์ด๋ฒคํธ ์ฌ์ฉํ๊ธฐ (0) | 2021.10.20 |
[React] React ์์ bootstrap ์ฌ์ฉํ๊ธฐ(ReactStrap) (0) | 2021.10.20 |
[React] HTTP ํต์ ์ ์ํ ๋ฐฉ๋ฒ (Fetch, Axios, Promise) (0) | 2021.10.20 |
๋๊ธ