๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
[๊ฐœ๋ฐœ] Practice/React

[React] props ๋Œ€์‹  redux ์‚ฌ์šฉํ•ด๋ณด๊ธฐ

by Connecting-the-dots 2022. 3. 28.
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก ์‹ค์Šต ํฌ์ธํŠธ!

  • ์ด๋ฒˆ์—๋Š” props ๋ฅผ ๋Œ€์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ธ redux ์— ๋Œ€ํ•ด์„œ ์กฐ๊ธˆ ๊ณต๋ถ€ํ•ด๋ณด์•˜๋‹ค.
  • ์•„์ง๊นŒ์ง€๋Š” ๋‚ด๊ฐ€ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ํ•˜์œ„ Component ๊ฐ€ ๋ณ„๋กœ ์—†๋‹ค๋ณด๋‹ˆ props ๋ณด๋‹ค ํŽธํ•œ์ง€์— ๋Œ€ํ•ด ๋…ผํ•˜๊ธฐ๋Š” ์–ด๋ ต๊ธด ํ•˜๋‹ค.
  • ๋งˆ์ง€๋ง‰ redux ์ˆ˜์—…๊นŒ์ง€ ์ž˜ ๋“ค์–ด์„œ ์•ผ๋ฌด์ง€๊ฒŒ ์จ๋จน์–ด์•ผ๊ฒ ๋‹ค.

๐Ÿ’œ props ๋Œ€์‹ ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• ์ฐพ์•„๋ณด๊ธฐ

  • props ๋ฅผ ๋Œ€์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” Context API ๋‚˜ Redux ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
  • ์ด์ „์—๋Š” Context API ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์œผ๋ฏ€๋กœ, ์ด๋ฒˆ์—๋Š” Redux ๋ฅผ ์ด์šฉํ•ด๋ณด์•˜๋‹ค.
  • ์‚ฌ์‹ค, React ๋ฅผ ์ด์šฉํ•œ ์‹ค์ œ ์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” redux ๋ฅผ ์„ค์น˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์ด ์ข€ ๋” ๋งŽ๋‹ค.

๐Ÿ’œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ

๐Ÿค ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์— ํ‘œ ๋ ˆ์ด์•„์›ƒ ์ถ”๊ฐ€ํ•˜๊ธฐ

<div>
  <Table responsive>
    <thead>
      <tr>
        <th>#</th>
        <th>์ƒํ’ˆ๋ช…</th>
        <th>์ˆ˜๋Ÿ‰</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>์ƒํ’ˆ๋ช…</td>
        <td>์ˆ˜๋Ÿ‰</td>
      </tr>
      <tr>
        <td>2</td>
        <td>์ƒํ’ˆ๋ช…</td>
        <td>์ˆ˜๋Ÿ‰</td>
      </tr>
      <tr>
        <td>3</td>
        <td>์ƒํ’ˆ๋ช…</td>
        <td>์ˆ˜๋Ÿ‰</td>
      </tr>
    </tbody>
  </Table>
</div>
  • Cart.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ ๋’ค Cart Component ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ผ๋ฐ˜์ ์ธ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํŽ˜์ด์ง€์ฒ˜๋Ÿผ ํ‘œ ๋ ˆ์ด์•„์›ƒ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.
  • ๋น ๋ฅธ ๋ ˆ์ด์•„์›ƒ ๋””์ž์ธ์„ ์œ„ํ•ด ํ‘œ ๋ ˆ์ด์•„์›ƒ์€ React Bootstrap ์˜ table ์„ ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐํ•œ ํ›„ ์ˆ˜์ •์„ ํ•ด์ฃผ์—ˆ๋‹ค.

๐Ÿค ๋ผ์šฐํ„ฐ ์„ค์ •ํ•˜๊ธฐ

// ์ฝ”๋“œ ์ „์ฒด ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ฝ”๋“œ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

import Cart from './Cart';

function App() {

  return (
    <div className="App">

        <Switch>

          <Route path='/cart'>
            <Cart />
          </Route>

        </Switch>
      
    </div>
  );
}
  • ์ด์ œ ๊ธฐ์กด์— ๋ผ์šฐํ„ฐ๋ฅผ ์„ค์ •ํ•ด์ฃผ๋˜ ๋ถ€๋ถ„์œผ๋กœ ๊ฐ€์„œ /cart ๋ผ๋Š” ๊ฒฝ๋กœ๋กœ GET ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด Cart Component ๋ฅผ ๋ณด์—ฌ์ฃผ๋„๋ก ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค.
  • ๋ฌผ๋ก  Cart.js ํŒŒ์ผ์—์„œ Cart Component ๋ฅผ export ํ•ด์ฃผ๊ณ  App.js ํŒŒ์ผ์—์„œ import ํ•ด์•ผํ•œ๋‹ค๋Š” ์  ์žŠ์ง€ ๋ง์ž!
  • ์—ฌ๊ธฐ๊นŒ์ง€ ์™„๋ฃŒํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์—์„œ /cart ๋กœ ์ ‘์†ํ•˜๋ฉด Cart Component ๊ฐ€ ๋ณด์ธ๋‹ค.

๐Ÿ’œ redux ์„ค์น˜ ํ›„ ์…‹ํŒ…ํ•˜๊ธฐ

  • ์ด์ „์—๋Š” ์ตœ์ƒ์œ„ ํŒŒ์ผ์— state ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•œ ํ›„ props ๋กœ ์ „์†ก๋ฐ›์•˜๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” redux ๋ฅผ ์ด์šฉํ•ด์„œ ๋ณด๊ด€ํ•ด๋ณด์•˜๋‹ค.

๐Ÿค redux ์„ค์น˜ํ•˜๊ธฐ

// npm ์„ ์ด์šฉํ•  ๋•Œ
npm install redux react-redux

// yarn ์„ ์ด์šฉํ•  ๋•Œ
yarn add redux react-redux
  • Redux ๋ฅผ ์ด์šฉํ•˜๋ ค๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ 2๊ฐœ(redux, react-redux) ์„ค์น˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
    • redux ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
    • react-redux ๋Š” Redux ๋ฅผ React ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์œ„ ์ฝ”๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•˜์—ฌ ํ„ฐ๋ฏธ๋„์— ์ž…๋ ฅํ•ด์ฃผ๋ฉด 2๊ฐœ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์„ค์น˜๋œ๋‹ค.

๐Ÿค redux ์…‹ํŒ…ํ•˜๊ธฐ

// ์ฝ”๋“œ ์ „์ฒด ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ฝ”๋“œ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

import {Provider} from 'react-redux'; // 1๋‹จ๊ณ„
import { createStore } from 'redux'; // 3๋‹จ๊ณ„

let store = createStore(()=>{ // 3๋‹จ๊ณ„
  return [
    { id : 1, name : 'Red Knit', quan : 2 },
    { id : 0, name : 'White and Black', quan : 1 },
    { id : 3, name : 'Flowey', quan : 3 }
  ] 
});

ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <Provider store={store}> // 2๋‹จ๊ณ„, 4๋‹จ๊ณ„
        <App />
      </Provider>
    </BrowserRouter>
  </React.StrictMode>
);
  • redux ๋ฅผ ์ด์šฉํ•œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์„ ์…‹ํŒ…ํ•˜๋ ค๋ฉด index.js ํŒŒ์ผ์—์„œ ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
    • 1๋‹จ๊ณ„ : Provider ๋ฅผ react-redux ๋กœ๋ถ€ํ„ฐ import ํ•œ๋‹ค.
    • 2๋‹จ๊ณ„ : state ๊ฐ’์„ ๊ณต์œ ํ•˜๊ณ ์ž ํ•˜๋Š” Component ๋ฅผ <Provider></Provider> ๋กœ ๊ฐ์‹ธ์ค€๋‹ค.
      (๋‚˜์˜ ๊ฒฝ์šฐ, App Component ๋ฅผ ๊ฐ์‹ธ์ฃผ์–ด App Component ์œ๋งŒ ์•„๋‹ˆ๋ผ ๊ทธ ์•ˆ์˜ ๋ชจ๋“  HTML, Component ์—์„œ state ๋ฅผ props ์ „์†ก ์—†์ด ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.)
    • 3๋‹จ๊ณ„ : redux ์—์„œ  createStore() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ state ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ ๋‹ค.
      (createStore ๋ฅผ redux ๋กœ๋ถ€ํ„ฐ import ํ•œ ๋‹ค์Œ, createStore() ์•ˆ์— state ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝœ๋ฐฑํ•จ์ˆ˜์˜ ํ˜•ํƒœ๋กœ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.)
    • 4๋‹จ๊ณ„ : <Provider> ์— state ๋ฅผ props ์ฒ˜๋Ÿผ ๋“ฑ๋กํ•œ๋‹ค.

๐Ÿ’œ redux ์— ์ €์žฅํ•œ state ๋ฐ์ดํ„ฐ ๊บผ๋‚ด์“ฐ๊ธฐ

  • ์œ„์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฅผ redux ์— ์ €์žฅํ–ˆ๋‹ค๋ฉด Cart.js ํŒŒ์ผ์—์„œ state ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด์“ธ ์ˆ˜ ์žˆ๋‹ค.
  • ์ฆ‰, ์ด์ œ Cart Component ๋‚ด์˜ Table Component ์— ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
  • ๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” store ๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์œผ๋กœ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ props ์˜ ํ˜•ํƒœ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค. 

๐Ÿค ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  Component ๊ฐ€ ์žˆ๋Š” JavaScript ํŒŒ์ผ ํ•˜๋‹จ์— ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

function Store(state) {
    
    return {
        state : state        
    }
    
}
  • ์ด ํ•จ์ˆ˜๋Š” store ์•ˆ์— ์žˆ๋˜ state ๋ฅผ props ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  • return ์•ˆ์— { ๋ณ€์ˆ˜๋ช… : ๋ฐ›์•„์˜จ_state } ์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ๋ฉด store ์•ˆ์— ์žˆ๋˜ ๋ชจ๋“  state ๋ฐ์ดํ„ฐ๊ฐ€ props ๋กœ ๋“ฑ๋ก๋œ๋‹ค.
  • ๋ฌผ๋ก  ํ•„์š”ํ•œ state ๋งŒ { ๋ณ€์ˆ˜๋ช… : ๋ฐ›์•„์˜จ_state.name } ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋ฐ›์•„์™€ props ๋กœ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿค export default ๋’ค์— connect ํ•จ์ˆ˜ ๋„ฃ๊ธฐ

import { connect } from 'react-redux';
  • ์ผ๋‹จ ์œ„์™€ ๊ฐ™์ด react-redux ์—์„œ connect() ํ•จ์ˆ˜๋ฅผ import ํ•ด์˜จ๋‹ค.
  • ํ•˜๋‹จ์—์„œ export default connect()() ํ˜•ํƒœ๋กœ export default ๋ฌธ์„ ์ž‘์„ฑํ•˜๋‹ค๋ณด๋ฉด ์ž๋™์œผ๋กœ import ๋˜๊ธฐ๋„ ํ•œ๋‹ค.
export default connect(Store)(Cart);
  • ์ด์ œ ์ด์ „์— Cart component ๋ฅผ export ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ–ˆ๋˜ ์ฝ”๋“œ์ธ export default Cart ๋ฅผ ์ˆ˜์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  • connect() ํ•จ์ˆ˜์— ์•„๊นŒ ๋งŒ๋“  Store ํ•จ์ˆ˜๋ฅผ ์ง‘์–ด ๋„ฃ์–ด์ค€ ๋‹ค์Œ, Cart Component ๋„ ์†Œ๊ด„ํ˜ธ ์•ˆ์— ์ง‘์–ด๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ๋”ฐ๋ผ์„œ, ์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด redux store ์— ์žˆ๋˜ ๋ฐ์ดํ„ฐ๋“ค์ด props ๋กœ ์—ฎ์ธ ์ฑ„๋กœ Component ๊ฐ€ export ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๐Ÿค props ์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ

function Cart(props) {

  return(
    <div>
      <Table responsive>
        <thead>
          <tr>
            <th>#</th>
            <th>์ƒํ’ˆ๋ช…</th>
            <th>์ˆ˜๋Ÿ‰</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>1</td>
            <td>props.state[0].name</td>
            <td>props.state[0].quan</td>
          </tr>
          <tr>
            <td>2</td>
            <td>props.state[1].name</td>
            <td>props.state[1].quan</td>
          </tr>
          <tr>
            <td>3</td>
            <td>props.state[2].name</td>
            <td>props.state[2].quan</td>
          </tr>
        </tbody>
      </Table>
    </div>
  )

}
  • ์ด์ œ props ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์„ ํ•˜๋ ค๋ฉด, Cart Component ์— props ๋ผ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ Store() ํ•จ์ˆ˜์—์„œ state ๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ €์žฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋ฉด ๋œ๋‹ค.

๐Ÿ’œ map ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ํ™•์žฅ์„ฑ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ธฐ

// ์ฝ”๋“œ ์ „์ฒด ๋ฏธ๋ฆฌ๋ณด๊ธฐ
// ์ฝ”๋“œ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ๋ถˆํ•„์š”ํ•œ ๋ถ€๋ถ„์€ ์ œ์™ธํ–ˆ๋‹ค.

<Table responsive>
    <thead>
    <tr>
        <th>#</th>
        <th>์ƒํ’ˆ๋ช…</th>
        <th>์ˆ˜๋Ÿ‰</th>
    </tr>
    </thead>
    <tbody>
        {
            props.state.map((item, idx)=>{
                return (
                    <tr key={idx}>
                        <td>{ idx + 1 }</td>
                        <td>{item.name}</td>
                        <td>{item.quan}</td>
                    </tr>
                )
            })
        }
    </tbody>
</Table>
  • ๊ฐ•์˜๋Š” ๋ฐ์ดํ„ฐ๋ฐ”์ธ๋”ฉ์œผ๋กœ ๋๋‚ฌ์ง€๋งŒ.. ์—ญ์‹œ ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋‘๊ณ ๋ณผ ์ˆ˜๋Š” ์—†์—ˆ๋‹ค!
  • ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋งŒ๋“ค๋ฉด ํ™•์žฅ์„ฑ์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ map ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์˜€๋‹ค.
  • ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง€๊ณ  ํ™•์žฅ์„ฑ์ด ์ข‹์•„์ง„ ๊ฑธ ๋ณด๋‹ˆ ๋งˆ์Œ์ด ํ‰์˜จํ•ด์กŒ๋‹ค.
  • ๋งˆ์ง€๋ง‰์œผ๋กœ div ๋ฐ•์Šค๋งŒ ์กฐ๊ธˆ ๋” ์˜ˆ์˜๊ฒŒ ์ˆ˜์ •ํ•ด์ฃผ์—ˆ๋‹ค.

 

728x90
๋ฐ˜์‘ํ˜•