Redux: ์ปจํ…Œ์ด๋„ˆ ๋Œ€ ๊ตฌ์„ฑ ์š”์†Œ?

์— ๋งŒ๋“  2015๋…„ 09์›” 19์ผ  ยท  46์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: reduxjs/redux

์˜ˆ์ œ์—๋Š” ํ•ญ์ƒ "container"๋ผ๋Š” ํด๋”์™€ "component"๋ผ๋Š” ํด๋”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ถ„๋ฆฌ์— ๋Œ€ํ•œ ์ƒ๊ฐ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

"์ปจํ…Œ์ด๋„ˆ"๋Š” ์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๊นŒ ์•„๋‹ˆ๋ฉด ๋ผ์šฐํŒ… ๊ตฌ์„ฑ ์š”์†Œ ๋˜๋Š” ๋‹ค๋ฅธ ๊ฒƒ์ž…๋‹ˆ๊นŒ? "๊ตฌ์„ฑ ์š”์†Œ"์•„๋ž˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ํ•ญ์ƒ ๋ฉ์ฒญํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ?

docs question

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ์˜ค์ง props์— ์˜ํ•ด์„œ๋งŒ ๊ตฌ๋™๋˜๊ณ  Redux์™€ ๋Œ€ํ™”ํ•˜์ง€ ์•Š๋Š” ์บก์Šํ™” ๋œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ components ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. "๋‹จ์ˆœํ•œ ๊ตฌ์„ฑ ์š”์†Œ"์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋ผ์šฐํ„ฐ, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ ์˜ค๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์— ๊ด€๊ณ„์—†์ด ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Redux, Router ๋“ฑ์„ ์ธ์‹ํ•˜๋Š” React ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ containers ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋“ค์€ ์•ฑ๊ณผ ๋” ๋งŽ์ด ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. "์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ"์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  46 ๋Œ“๊ธ€

๋‚˜๋ฅผ ์œ„ํ•ด container ๋Š” ๊ฒฝ๋กœ์˜ ํ•ธ๋“ค๋Ÿฌ์ด๋ฉฐ ํ•ด๋‹น ๊ฒฝ๋กœ์— ๋Œ€ํ•œ redux์˜ ์ƒํƒœ๋„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‚ด ์ƒํƒœ๋ฅผ ์†Œํ’ˆ์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด

container / properties.jsx

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect }  from 'react-redux';

import * as actions from 'actions/properties';
import Filter from 'components/properties/filter';
import List from 'components/properties/list';
import Pagination from 'components/properties/pagination';

class PropertiesContainer extends Component {
  render() {
    return (
      <section>
        <Filter filter={this.props.properties.params.filter} />
        <List items={this.props.properties.items} isFetching={this.props.properties.isFetching} />
        <Pagination pagination={this.props.properties.params.pagination} />
      </section>
    );
  }
}

function mapState(state) {
  const { properties } = state;

  return { properties };
}

function mapDispatch(dispatch) {
  return {
    actions: bindActionCreators(actions, dispatch),
  };
}

const Connector = connect(mapState, mapDispatch)(PropertiesContainer);

export default Connector;

์˜ˆ๋ฅผ ๋“ค์–ด

components / properties / pagination.jsx

import React, { Component } from 'react';
import Pager from 'components/ui/pager';

class Pagination extends Component {
  render() {
    const { total, offset, limit } = this.props.pagination;
    const current = offset / limit;

    return (
      <Pager total={total} current={current} />
    )
  }
}

export default Pagination;

์ œ๊ณต ํ•œ ๋งํฌ์—์„œ ์ฝ๊ธฐ :

"A container does data fetching and then renders its corresponding sub-component. "

"์ปจํ…Œ์ด๋„ˆ"๊ฐ€ ์‹ค์ œ๋กœ redux์—์„œ "์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ"๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ ๊ฐ™์€ ๋Š๋‚Œ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ / ํŽ˜์ด์ง€๋Š” ์ž์ฒด ํด๋”๋ฅผ ๊ฐ€์ ธ์•ผํ•ฉ๋‹ˆ๋‹ค.

"์ปจํ…Œ์ด๋„ˆ"์™€ "๋ผ์šฐํŠธ ์ฒ˜๋ฆฌ๊ธฐ"๊ฐ€ ์–ด๋–ค ์‹ ์œผ๋กœ๋“  ๊ด€๋ จ๋˜์–ด์žˆ๋Š” ์ด์œ ๋ฅผ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฒฝ๋กœ๋ณ„๋กœ ์•ฑ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ผ๋ฐ˜์ ์ธ ๊ด€ํ–‰์ž…๋‹ˆ๋‹ค. @theaqua๊ฐ€ ์ง€์ ํ–ˆ๋“ฏ์ด ๊ฐ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๊ธฐ / ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์Šค๋งˆํŠธ / ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. combineReducers๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋™์ผํ•œ ๋ผ์ธ์„ ๋”ฐ๋ผ ์ƒํƒœ, ๊ฒฝ๋กœ ๋ฐ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋ถ„๋ฆฌ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ๋“ค์€ ์ข…์ข… ํ•จ๊ป˜ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

@ronag ์ปจํ…Œ์ด๋„ˆ ์™€ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ redux ์ปค๋„ฅํ„ฐ๋ฅผ ํ•œ๊ณณ์— ๋†“์„ ์ˆ˜ ์—†์Šต๋‹ˆ๊นŒ? ๋งค์šฐ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค.

๋‚ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—๋Š” 3 ๊ฐœ์˜ ๊ฒฝ๋กœ / ํŽ˜์ด์ง€ ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— ์ €๋Š” ๋งŽ์€ ๋…๋ฆฝ์  ์ธ ํŒจ๋„ / ๋ชจ๋“ˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ connect ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ ํŒจ๋„ ์ธก๋ฉด์—์„œ ๋ถ„ํ• ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ์—์„œ ์†Œํ’ˆ์œผ๋กœ์˜ ๋ชจ๋“  ๋งคํ•‘๊ณผ ๋‹จ์ผ ํŒŒ์ผ์—์„œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ ์˜ค๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์œ ์ง€ ๊ด€๋ฆฌ ํ•  ์ˆ˜ โ€‹โ€‹์—†์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ๋™์ผํ•œ ์œ„์น˜์—์„œ ๊ฐ€์ ธ ์˜ค๋Š” ๊ฒฝ์šฐ.

3 ๊ฐœ์˜ ๊ฒฝ๋กœ๊ฐ€์žˆ๋Š” ๊ฒฝ์šฐ 3 ๊ฐœ์˜ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด A.jsx ์—์„œ B.jsx ๋ฐ C.jsx /containers .

๊ฐ ์ปจํ…Œ์ด๋„ˆ์—์„œ redux ์ƒํƒœ ๋ฐ ์ž‘์—… ๋ฐ”์ธ๋”ฉ์˜ ์ผ๋ถ€ (์ „์ฒด๊ฐ€ ์•„๋‹˜)๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๊ฒƒ์„ ๋‚ด ์˜ˆ์ œ์™€ ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ (๋‚ด ํŒ€) ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋งค์šฐ ์œ ์ง€ ๋ณด์ˆ˜์˜ - ์—ฐ๊ฒฐ ๋Œ์•„ ์˜ค๋Š” ํ•ญ์ƒ์—์„œ ์•ก์…˜ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ containers , ๊ทธ๊ฒƒ์€ ๋  ๊ฒƒ ์ ๋„ components ๋‚ด ์˜ˆ์—์„œ์™€ ๊ฐ™์ด ์ข…์ข… ๋ฌด ์ž‘๊ณ ํ•˜๋Š” ( ).

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ œ์•ˆ์„ ์ดํ•ดํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ ์˜ค๊ธฐ๋ฅผ ๊ฑฐ๊ธฐ์— ๋„ฃ์œผ๋ฉด ๊ทธ 3 ๊ฐœ์˜ ํŒŒ์ผ์ด ๋งค์šฐ ๋ณต์žกํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์›์ธ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ "Login, App, Logout"์ด๋ฉฐ App์€ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

๊ฐ ๊ตฌ์„ฑ ์š”์†Œ์— ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ์™€ ํ‘œ์‹œ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€์žˆ๋Š” Relay ๋„ˆ๋ฌด ํŽธํ–ฅ๋˜์–ด์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๋‹น์‹ ์˜ ์ œ์•ˆ์„ ์‹œ๋„ํ•˜๊ณ  ์šฐ๋ฆฌ๊ฐ€ ๋๋‚˜๋Š” ๊ณณ์„ ๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์˜ค์ง props์— ์˜ํ•ด์„œ๋งŒ ๊ตฌ๋™๋˜๊ณ  Redux์™€ ๋Œ€ํ™”ํ•˜์ง€ ์•Š๋Š” ์บก์Šํ™” ๋œ React ์ปดํฌ๋„ŒํŠธ๋ฅผ components ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. "๋‹จ์ˆœํ•œ ๊ตฌ์„ฑ ์š”์†Œ"์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๋ผ์šฐํ„ฐ, ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ ์˜ค๊ธฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ์— ๊ด€๊ณ„์—†์ด ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

Redux, Router ๋“ฑ์„ ์ธ์‹ํ•˜๋Š” React ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ containers ๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋“ค์€ ์•ฑ๊ณผ ๋” ๋งŽ์ด ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. "์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ"์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

@gaearon : ์™„๋ฒฝํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์˜ˆ๊ฐ€ ๋ช…ํ™• ํ•ด์ง‘๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

@gaearon ๋”ฐ๋ผ์„œ "dumb ๊ตฌ์„ฑ ์š”์†Œ"๋Š” ์ƒํƒœ ๋น„ ์ €์žฅ ๊ตฌ์„ฑ ์š”์†Œ๋กœ, React 0.14 ์ดํ›„ ๋” ๊ฐ„๋‹จํ•œ ๊ตฌ๋ฌธ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

var Aquarium = (props) => {
  var fish = getFish(props.species);
  return <Tank>{fish}</Tank>;
};

์ œ๊ฐ€ ๋งž์Šต๋‹ˆ๊นŒ?

@soulmachine ๋„ต.

๋ฐ˜๋“œ์‹œ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ตฌ๋ฌธ์€ ์š”์ ์ด ์•„๋‹™๋‹ˆ๋‹ค.

"Dumb"์ปดํฌ๋„ŒํŠธ๋Š” "presentational"์ปดํฌ๋„ŒํŠธ๋ผ๊ณ ๋„ํ•˜๋ฉฐ props๋กœ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  Redux๋ฅผ ์ธ์‹ํ•˜์ง€ ์•Š๊ณ  ๋ชจ์–‘ ๋งŒ ์ง€์ •ํ•˜๊ณ  ๋™์ž‘์€ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.

@theaqua @gaearon ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

"์ปจํ…Œ์ด๋„ˆ"๋ผ๋Š” ์šฉ์–ด๋Š” react / redux ๋ช…๋ช…๋ฒ•์—์„œ ์ด๋ฏธ ๊ฝค ์ธ๊ธฐ๊ฐ€ ์žˆ์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ / ๊ทธ๋ž˜ํ”ฝ ์ปจํ…Œ์ด๋„ˆ์™€์˜ ํ˜ผ๋™์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ฐ€ ์ž‘์—…์ค‘์ธ ํ”„๋กœ์ ํŠธ์—์„œ "์ปค๋„ฅํ„ฐ"๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

btw, ๊ทธ๋“ค์„ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•ž์„œ rackt / react-redux # 170์—์„œ ๋…ผ์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ components ํด๋”์— ๋ณด๊ด€ํ•˜๊ณ  ํ”„๋ฆฌ์   ํ…Œ์ด์…˜ ํด๋”๋Š” components/presentational ์•ˆ์— ํ•œ ๋‹จ๊ณ„ ๋” ๊นŠ๊ฒŒ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„๋‹Œ ์•ฑ์˜ ์ผ๋ถ€์—์„œ ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@gaearon dispatch "๋ฉ์ฒญํ•œ"๋˜๋Š” "์Šค๋งˆํŠธ ํ•œ"๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๊นŒ? ํŠนํžˆ ๋””์ŠคํŒจ์น˜๋ฅผ โ€‹โ€‹์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฒคํŠธ๋ฅผ ๋งจ ์œ„ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ฒ„๋ธ” ๋งํ•˜๋Š” ๋Œ€์‹  ์ž‘์—…์„ ๋””์ŠคํŒจ์น˜ํ•˜๋Š” ๋ฆฌํ”„ ๋˜๋Š” ์ค‘๊ฐ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, connect() ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์„ ํ˜ธํ•˜์ง€๋งŒ ๊ฐ€๋” ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์•ก์…˜ ์ œ์ž‘์ž๋Š” ์†Œํ’ˆ์œผ๋กœ ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ถ€๋ฅด๋Š”์ง€๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. :-)

์ปดํฌ๋„ŒํŠธ ๋ชจ๋“ˆ์„ ๊ตฌ์ถ• ํ•  ๋•Œ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด <NavMenu> ๋Œ€ํ•ด ๋ณ„๋„์˜ ๋…ธ๋“œ ๋ชจ๋“ˆ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.

import {NavMenu} from 'my-redux-aware-components';

export function myPage(props) {
  return (<div><NavMenu routes={props.routes} /></div>);
}

๊ทธ๋ž˜์„œ ์ด๋ฆ„์„ 'NavMenuContainer'๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ๋‚˜์—๊ฒŒ ์ด์ƒํ•ด ๋ณด์ธ๋‹ค. ๋Œ€์‹  ๊ตฌ์„ฑ ์š”์†Œ ์ด๋ฆ„์„ NavMenuComponent๋กœ ์ง€์ •ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ๋‘˜ ๋‹ค ๋‚˜์—๊ฒŒ ์ด์ƒํ•ด ๋ณด์ธ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ƒํƒœ์—์„œ ํ•˜๋‚˜์˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ ์˜ค๊ธฐ ์œ„ํ•ด ์—ฐ๊ฒฐ ๋งŒ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœ์„ ์ธ๋ผ์ธํ•˜๋Š” ๊ฒƒ์ด ์ •๋ง ๋‚˜์œ๊ฐ€์š”?

export default const NavMenu = connect(state => ({currentPath:state.routing.path})(React.createClas({...}));

์ปค๋„ฅํŠธ ์ฝœ์„ ์ธ๋ผ์ธํ•˜๋Š” ๊ฒƒ์ด " ๊ดœ์ฐฎ์€ "๋•Œ

์–ด๋–ป๊ฒŒ ๋ถ€๋ฅด๋“  ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค. NavMenu ๋ผ๊ณ  ๋ถ€๋ฅด์ง€ ์•Š๊ฒ ์Šต๋‹ˆ๊นŒ?

์ธ๋ผ์ธ์— ๋Œ€ํ•œ ์งˆ๋ฌธ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.
๋น„๊ตํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ œ์‹œํ•˜๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.
์˜ต์…˜ 1 (๋ณ„๋„์˜ ํŒŒ์ผ 2 ๊ฐœ, ์ปจํ…Œ์ด๋„ˆ ์šฉ 1 ๊ฐœ, ๊ตฌ์„ฑ ์š”์†Œ ์šฉ 1 ๊ฐœ)

์ปจํ…Œ์ด๋„ˆ / NavMenu

import {connect} from 'react-redux';
import NavMenu from '../components/NavMenu';

export default connect(state => ({currentPath:state.routing.path})(NavMenu);

์˜ต์…˜ 2 (๋‘˜ ๋‹ค ํฌํ•จํ•˜๋Š” ๋‹จ์ผ ํŒŒ์ผ 1 ๊ฐœ) :
๊ตฌ์„ฑ ์š”์†Œ / NavMenu

import {connect} from 'react-redux';

export default connect(state => ({currentPath:state.routing.path})(React.createClass({
  render() {
      return <div>the menu {this.props.currentPath} goes here</div>;
  }
});

๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ ์ƒํƒœ์—์„œ ํ•„์š”ํ•œ currentPath์— ๋Œ€ํ•ด ์•ฝ๊ฐ„๋งŒ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…Œ์ด๋„ˆ์™€ ๊ตฌ์„ฑ ์š”์†Œ ์ธ ๋‹จ์ผ ํŒŒ์ผ (2 ๊ฐœ์˜ ํŒŒ์ผ์ด ์•„๋‹Œ)์„ ๊ฐ–๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ•ญ์ƒ ํ”ผํ•ด์•ผ ํ•  ์ผ์ž…๋‹ˆ๊นŒ, ์•„๋‹ˆ๋ฉด ์ด์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์— ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๊นŒ?

๋ฌผ๋ก  ๊ฐ„๋‹จํ•œ ๊ฒฝ์šฐ์—์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ž˜์š” ์ข‹์•„์š”. ์–ธ์ œ ์„ ์„ ๊ทธ๋ฆฌ๊ณ  "์ข‹์•„, ์ด๊ฑธ 2 ๊ฐœ์˜ ํŒŒ์ผ๋กœ ์˜ฎ๊ธฐ ๊ฒ ์–ด"๋ผ๊ณ  ๋งํ•˜๊ฒ ์Šต๋‹ˆ๊นŒ?

๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋ฐ์ดํ„ฐ ๋ฌธ์ œ (๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰ / ๊ณ„์‚ฐ ๋ฐฉ๋ฒ•, ์ž‘์—… ์ „๋‹ฌ ๋ฐฉ๋ฒ•)์™€ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ (๋ชจ์–‘)์„ ํ˜ผํ•ฉํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ. ๋‹ค๋ฅธ ๋งฅ๋ฝ์—์„œ ํ…Œ์ŠคํŠธํ•˜๊ฑฐ๋‚˜ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ค์›Œ ์งˆ ๋•Œ.

@benmonro ํ•œ ๊ฐ€์ง€ ๋” ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ๋ชจ๋“ˆ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒฝ์šฐ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์•ฑ ์ƒํƒœ ํŠธ๋ฆฌ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ์—ฐ๊ฒฐํ•˜๊ฑฐ๋‚˜ ๋‹ค์–‘ํ•œ ์ƒํƒœ๋กœ ํ”„๋ ˆ์  ํ…Œ์ด์…˜์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์ด ๊ตฌ์„ฑ ์š”์†Œ ๋ชจ๋“ˆ ๋‚ด์— connect ์žˆ์œผ๋ฉด์ด ๊ธฐ๋Šฅ์ด ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @gaearon

@sompylasar ์•„์ฃผ ์ข‹์€ ์ง€์ ์ž…๋‹ˆ๋‹ค! ๊ฐ์‚ฌ

๋‚ด ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜์—ฌ ๋ถ„๋ฆฌ ํ•œ ํ›„, ์ด์ œ ํ›„์† ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๋‹ค. <NavMenuItem> ์ปจํ…Œ์ด๋„ˆ๋„ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. <NavMenu> ๊ตฌ์„ฑ ์š”์†Œ๋Š” <NavMenuItem /> ๋ฅผ ํ•˜์œ„ ์š”์†Œ๋กœ ์ฐธ์กฐํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. NavMenu ๊ตฌ์„ฑ ์š”์†Œ์—์„œ import NavMenuItem from '../containers/NavMenuItem' ๋งŒ ์ˆ˜ํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์ด๊ฒƒ์ด @sompylasar์˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ ๊นŒ?

NavMenuItem์„ NavMenu์˜ ์†Œํ’ˆ์„ ํ†ตํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๊ฐ€ ์ „๋‹ฌ ๋œ ์ˆœ์ˆ˜ํ•œ ํ‘œํ˜„ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งŒ๋“ค ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ณ„๋„๋กœ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ๊ฐœ์˜ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ (NavMenu, NavMenuItem) ๋ฐ ํ•˜๋‚˜์˜ ์—ฐ๊ฒฐ๋œ (connect (...) (NavMenuItem)) ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํ† ๋ก ์—์„œ ๋‚ด๊ฐ€ ๋†“์นœ ๊ฒƒ์€ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ์žˆ์œผ๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์–•์€ ๋ Œ๋”๋ง์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ๋…ธ์ถœ ํ•œ ๋‹ค์Œ ๊ฐœ๋ณ„์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ฒƒ์„ ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ์ด ๊ฒฝ์šฐ ๋‘ ํŒŒ์ผ์ด ๋‘ ๊ฐ€์ง€๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œํ•˜๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ํŒŒ์ผ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋˜ํ•œ ์—ฌ๊ธฐ์„œ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ์™€ ํ”„๋ฆฌ์   ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋…๋ฆฝ์ ์ด๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค.

FWIW ํ˜„์žฌ ์ƒ๊ฐ์„ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๋ฐ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ๋œ ๋ฌธ์„œ์—์„œ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ๋” ์ด์ƒ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
http://redux.js.org/docs/basics/UsageWithReact.html

Redux ๋ฌธ์„œ์˜ ์‹ค์ œ ์˜ˆ์ œ์—์„œ @gaearon ์€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ž์‹์œผ๋กœ ๊ฐ€์งˆ ์ˆ˜์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์ž˜๋ชป? ์ด๊ฒƒ์ด ๋‚ด๋ถ€์—์„œ ๋˜‘๋˜‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฉ์ฒญํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๊ทธ๋Ÿฌ๋‚˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ณ„์ธต ๊ตฌ์กฐ์˜ ์ตœ์‹  ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

Simple Data List ๊ตฌ์„ฑ ์š”์†Œ (Dumb)๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์•ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ ์•ˆ์—๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์ด ์ƒ์ ์— ์—ฐ๊ฒฐ๋˜์–ด์•ผํ•˜๋ฏ€๋กœ ์Šค๋งˆํŠธ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ๊ดœ์ฐฎ์ง€ ๋งŒ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๊ฐ์‚ฌ!

์ด๊ฒƒ์ด ๋‚ด๋ถ€์—์„œ ๋˜‘๋˜‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฉ์ฒญํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ ์„ค์ •์ด ์กฐ๊ธˆ ๋” ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค (์Šคํ† ์–ด๋„ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•จ). ์ด๊ฒƒ์ด ๋ถˆํŽธํ•œ ๊ฒฝ์šฐ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‚ด๋ถ€๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก children ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋” ๋งŽ์€ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถ€์„œ๋Š” ๊ท€ํ•˜์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์œผ๋ฉฐ ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„ (์ž‘์„ฑ ์šฉ์ด์„ฑ, ๋ฆฌํŒฉํ† ๋ง, ํ…Œ์ŠคํŠธ ๋“ฑ)๋ฅผ ํ‰๊ฐ€ํ•˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง์ ‘ ์„ ํƒํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ข‹์Šต๋‹ˆ๋‹ค. ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์‚ฌ๋ก€๋ณ„๋กœ ํ‰๊ฐ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๊ฐ์‚ฌ!!

Il lunedรฌ 2016 ๋…„ 2 ์›” 8 ์ผ, Dan Abramov [email protected] ha
์Šคํฌ ๋ฆฌํ†  :

์ด๊ฒƒ์ด ๋‚ด๋ถ€์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ๋ฉ์ฒญํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ์„ฑ์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
๋˜‘๋˜‘ํ•œ ์‚ฌ๋žŒ?

์ด๋กœ ์ธํ•ด ํ…Œ์ŠคํŠธ ์„ค์ •์ด ์กฐ๊ธˆ ๋” ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค (์ดˆ๊ธฐํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ƒ์ ๋„). ๋ถˆํŽธํ•  ๋•Œ ๋” ์ถ”์ถœ
์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž์‹์„ ํ—ˆ์šฉํ•˜๋Š” ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ
๋‚ด๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถ€์„œ๋Š” ๊ท€ํ•˜์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ์œผ๋ฉฐ
ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„ (์ž‘์„ฑ ์šฉ์ด์„ฑ, ๋ฆฌํŒฉํ† ๋ง, ํ…Œ์ŠคํŠธ ๋“ฑ) ํ‰๊ฐ€
๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง์ ‘ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค.

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/rackt/redux/issues/756#issuecomment -181143304.

๋ฃจ์นด ์ฝœ๋กœ๋„ฌ๋กœ
+39345 8948718
๋ฃจ์นด. [email protected]

'๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ ์š”์†Œ'๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ๋ผ์šฐํ„ฐ / ๋‚ด๋น„๊ฒŒ์ดํ„ฐ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ์ผ ๊ตฌ์„ฑ ์š”์†Œ์— ์žˆ์–ด์•ผํ•˜๋Š” ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ์ด ๋ž˜ํ•‘ ๊ตฌ์„ฑ ์š”์†Œ๋Š” '์ปจํ…Œ์ด๋„ˆ์˜ ๋ฉ์ฒญํ•œ ํ‘œํ˜„ ์ปจํ…Œ์ด๋„ˆ'๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@ Emilios1995 ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค ...
๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ํŽ˜์ด์ง€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ ˆ์ด์•„์›ƒ ๊ตฌ์„ฑ ์š”์†Œ์—๋Š” ๋ฉ”๋‰ด, ๋จธ๋ฆฌ๊ธ€, ๋ฐ”๋‹ฅ ๊ธ€์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๋Š” ํŽ˜์ด์ง€์—์„œ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ์ „๋‹ฌํ•œ ์ž์‹์ž…๋‹ˆ๋‹ค.
๋ฉ”๋‰ด์™€ ํ—ค๋”๋Š” ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค !! ๋”ฐ๋ผ์„œ ๋ ˆ์ด์•„์›ƒ์€ ์ž ์žฌ์ ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์ด์ง€๋งŒ ์ƒ์ ์— ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋ฉ”๋‰ด์™€ ํ—ค๋”๋ฅผ ๋ ˆ์ด์•„์›ƒ์œผ๋กœ ์ „๋‹ฌํ•˜๋ ค๊ณ ํ•˜๋ฉด ๋ ˆ์ด์•„์›ƒ (๊ตฌ์„ฑ ์š”์†Œ)์„ ๋ Œ๋”๋งํ•˜๊ณ  ๋ฉ”๋‰ด์™€ ํ—ค๋” (์ปจํ…Œ์ด๋„ˆ)๋ฅผ ์ „๋‹ฌํ•˜๋Š” ํŽ˜์ด์ง€ (์ปจํ…Œ์ด๋„ˆ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒํ•˜๋ฉด ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์ •ํ™•ํ•˜์ง€๋งŒ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋ฉ”๋‰ด์™€ ํ—ค๋”๋ฅผ ๋ฐ˜๋ณตํ•ด์•ผํ•˜๋Š”๋ฐ, ๊ทธ ๋น„ํŠธ๋Š” ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

@LucaColonnello ์ฝ”๋“œ ์—†์ด๋Š” ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๋กœ StackOverflow ์งˆ๋ฌธ์„ ์ƒ์„ฑ ํ•ด๋‹ฌ๋ผ๊ณ  ๋ถ€ํƒํ•ด๋„ ๋ ๊นŒ์š”? ๋‚˜๋Š” ๊ธฐ๋ปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ

Il sabato 27 2 ์›” 2016, Dan Abramov [email protected] ha
์Šคํฌ ๋ฆฌํ†  :

@LucaColonnello https://github.com/LucaColonnello ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค
์ฝ”๋“œ์—†์ด ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜์‹ญ์‹œ์˜ค. ๋‹น์‹ ์—๊ฒŒ
๋ฌธ์ œ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ๊ฐ€์žˆ๋Š” StackOverflow ์งˆ๋ฌธ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์‹ ๋ถ„์ฆ
๋ณด๊ณ  ๊ธฐ๋ปํ•˜์‹ญ์‹œ์˜ค.

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/reactjs/redux/issues/756#issuecomment -189672067.

๋ฃจ์นด ์ฝœ๋กœ๋„ฌ๋กœ
+39345 8948718
๋ฃจ์นด. [email protected]

@gaearon ๊ทธ๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์—์„œ ๋งŒ๋“  ์งˆ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค : http://stackoverflow.com/questions/35729025/should-the-route-handlers-use-containers-or-presentational-components? noredirect = 1 # comment59133192_35729025

๋งค์ฒด์— ๋Œ€ํ•œ Dan์˜ ๊ธฐ์‚ฌ
https://medium.com/@dan_abramov/smart -and-dumb-components-7ca2f9a7c7d0 # .3y00gw1mq
๋ชจ๋“  ๋ฌธ์ œ๋ฅผ ๋ช…ํ™•ํžˆํ•ฉ๋‹ˆ๋‹ค ...

2016-03-01 18:19 GMT + 01 : 00 Emilio Srougo [email protected] :

@gaearon https://github.com/gaearon ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์˜คํžˆ๋ ค ๋‚ด๊ฐ€ ์—ฌ๊ธฐ์„œ ๋งŒ๋“  ์งˆ๋ฌธ :
http://stackoverflow.com/questions/35729025/should-the-route-handlers-use-containers-or-presentational-components?noredirect=1#comment59133192_35729025

โ€”
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ฑฐ๋‚˜ GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/reactjs/redux/issues/756#issuecomment -190820426.

๋ฃจ์นด ์ฝœ๋กœ๋„ฌ๋กœ
+39345 8948718
๋ฃจ์นด. [email protected]

@gaearon ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ์— ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์ฐธ๊ณ  :

ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ์— ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”?

๋ชจ๋“  ์‚ฌ์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค์— ํŠน์ • ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜์—†๋Š” ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ this.props.children ์ˆ˜๋ฝํ•˜๊ณ  ํŠน์ • ์ปจํ…Œ์ด๋„ˆ ๋˜๋Š” ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‚ด๋ถ€๋กœ ์ „๋‹ฌํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋ ˆ์  ํ…Œ์ด์…˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

@gaearon React-Router์˜ [Root component] ์ปจํ…Œ์ด๋„ˆ ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๊นŒ?

  • route.js
<Route path="/" component={Root}>
      <IndexRoute component={Main} />
      <Route path="/account/signIn" component={SignIn} />
</Route>
  • root.js
export default class Root extends React.Component {
  render() {
    return (
      <div>
        <div id="container" className="container">
          {this.props.children}
        </div>
      </div>
    );
  }

๊ฐ์‚ฌ.

์œ„์˜ @gaearon ์€ ๋””์ŠคํŒจ์น˜์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•œ๋‹ค๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค (๋ถ€๋ชจ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ๊ณผ๋Š” ๋ฐ˜๋Œ€๋กœ).

์ด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ํ˜„์žฌ ๋ถ€๋ชจ๊ฐ€ ์ „๋‹ฌํ•˜๋Š” ๊ฐ์†๊ธฐ์—์„œ ๋งคํ•‘ ํ•  ์ˆ˜์žˆ๋Š” props๋„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด connect ์—์„œ ์˜ค๋„๋ก ๋ฆฌํŒฉํ„ฐ๋ง ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋˜๋Š” ownProps ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถ€๋ชจ์—๊ฒŒ ์ „๋‹ฌ๋˜๋„๋กํ•ฉ๋‹ˆ๋‹ค.

๋‘ ์˜ต์…˜๊ฐ„์— ๊ธฐ๋Šฅ / ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ๊ฑฐ๋Œ€ํ•œ redux ํ”„๋กœ์ ํŠธ ์ž‘์—… ๊ฒฝํ—˜์ด ๋งŽ์ง€ ์•Š์ง€๋งŒ react / redux ํŒŒ์ผ ๊ตฌ์กฐ ์ตœ์ ํ™”์— ๋Œ€ํ•ด ๋งŽ์€ ์—ฐ๊ตฌ์™€ ์ƒ๊ฐ์„ ํ•ด์™”์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์˜๋ฏธ๊ฐ€ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

src/
  components/
    header/ 
      navigation.js # nav menu list
      index.js # Header component
  modules/
    header/
      actions.js # header actions (sticky scroll, collapse mobile menu, etc...)
      reducer.js # header actions reducer (export to modules index)
      index.js # HeaderContainer (connect to Header component)
    index.js # combineReducers and export default configureStore (and middleware)

๋˜ ๋‹ค๋ฅธ ๊ฐœ๋… :

src/
  components/
    navigation.js
    logo.js
    link.js
    list.js
    item.js
  modules/
    header/
      actions.js # header actions 
      wrapper.js # header class (smart) component - to wrap header with functionality (was previously classified as container)
      container.js # header functional (dumb) component - to contain universal components
      index.js # header actions reducer - to export into modules rootReducer 

๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ, ์ปจํ…Œ์ด๋„ˆ ๋ฐ redux ๋ชจ๋“ˆ์„ ๋ณ„๋„๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚ซ์Šต๋‹ˆ๊นŒ (๋™์ผํ•œ ์ด๋ฆ„์„ ๊ณต์œ ํ•˜๋”๋ผ๋„)? ์ž…๋ ฅ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์ˆ˜์ค€์˜ react-redux ํ”„๋กœ์ ํŠธ๋กœ ์ž‘์—… ํ•ด ์™”์œผ๋ฉฐ ์ œ ๊ฒฝํ—˜์„ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ์˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ „์ ์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„์—๊ฒŒ ๋‹ฌ๋ ค ์žˆ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. React์˜ ๋ชฉ์ ์ด UI ๊ธฐ๋ฐ˜์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋ผ๋Š” ์ ์—์„œ ๋น„์‹ค์šฉ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…Œ์ด๋„ˆ / ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜ ๋ณ€ํ˜•์„ ๋”ฐ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ €๋Š” ๋ชจ๋“ˆ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ „์ฒด ํ”„๋กœ์ ํŠธ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ƒ๊ฐ ํ•ด๋ƒˆ๊ณ  ์ง€๊ธˆ๊นŒ์ง€ ํ™•์žฅ ์„ฑ, ์œ ์ง€ ๋ณด์ˆ˜์„ฑ ๋ฐ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ์ธก๋ฉด์—์„œ ์ •๋ง ์ž˜ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

image
image
image

์ €์—๊ฒŒ๋Š” ์ปจํ…Œ์ด๋„ˆ์™€ ์Šค๋งˆํŠธ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ •ํ™•ํžˆ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ์ •์˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์ปจํ…Œ์ด๋„ˆ / ์Šค๋งˆํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” JSX ๋งˆํฌ ์—… + ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ + API ํ˜ธ์ถœ + redux์˜ ์—ฐ๊ฒฐ / MSTP / MSDP๋ฅผ ํฌํ•จํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ž…๋‹ˆ๋‹ค.
๋ฉ์ฒญํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ˆœ์ˆ˜ํ•˜๊ฒŒ ํ‘œํ˜„์ ์ด๊ณ  ๊ธฐ๋Šฅ์ ์ธ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰