Redux: λ¬Έμ„œ: React Router와 ν•¨κ»˜ μ‚¬μš©

에 λ§Œλ“  2015λ…„ 08μ›” 27일  Β·  61μ½”λ©˜νŠΈ  Β·  좜처: reduxjs/redux

μ‚¬λžŒλ“€μ€ μš°λ¦¬κ°€ React Routerλ₯Ό μ§€μ›ν•˜μ§€ μ•Šκ±°λ‚˜ μž‘λ™ν•˜λ €λ©΄ redux-react-router 와 같은 νŠΉλ³„ν•œ 것이 ν•„μš”ν•˜κ±°λ‚˜ 심지어 React 0.14κΉŒμ§€ μž‘λ™ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 인상을 λ°›μŠ΅λ‹ˆλ‹€.

ν˜„μž¬μ™€ ​​같이 Reduxλ₯Ό React Router 0.13 λ˜λŠ” 1.0κ³Ό ν•¨κ»˜ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
(그런데 Redux의 초기 릴리슀 μ΄ν›„μ—λŠ” μ‚¬μ‹€μ΄μ—ˆμŠ΅λ‹ˆλ‹€.)

μ‹œκ°„ μ—¬ν–‰κ³Ό 같은 일뢀 κΈ°λŠ₯은 RR μΈ‘μ—μ„œ 일뢀 지원을 κΈ°λ‹€λ €μ•Ό ν•˜μ§€λ§Œ μ΄λŠ” μ£Όμš” λ¬Έμ œμ™€ 관련이 μ—†μŠ΅λ‹ˆλ‹€. μ‚¬λžŒλ“€μ€ μ˜€λŠ˜λ‚  λΌμš°νŒ…μ„ μ‚¬μš©ν•  수 μ—†λ‹€κ³  μƒκ°ν•˜μ—¬ ν˜Όλž€μŠ€λŸ¬μ›Œν•©λ‹ˆλ‹€. μ΄λŠ” 잘λͺ»λœ κ²ƒμž…λ‹ˆλ‹€.

이 리포지토리에 ν¬ν•¨λœ μ‹€μ œ 예제 λŠ” React Routerλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. λΌμš°ν„°κ°€ μ—†λŠ” μ•±μ—μ„œ μ΅œμƒμœ„ ꡬ성 μš”μ†Œλ₯Ό λž˜ν•‘ν•˜λŠ” κ²ƒμ²˜λŸΌ <Router> λ₯Ό <Provider> 둜 λž˜ν•‘ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

μ•‘μ…˜ μƒμ„±μžμ—μ„œ μ „ν™˜ν•˜λ €λ©΄ router μΈμŠ€ν„΄μŠ€λ₯Ό μ•‘μ…˜ μƒμ„±μžμ—κ²Œ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜κ³  μ›ν•˜λŠ” 경우 ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. Redux μ €μž₯μ†Œμ—μ„œ λΌμš°ν„° μƒνƒœλ₯Ό 읽으렀면 경둜 변경에 λŒ€ν•œ μž‘μ—…μ„ μ‹€ν–‰ν•˜κ³  이λ₯Ό μ²˜λ¦¬ν•  λ¦¬λ“€μ„œλ₯Ό μž‘μ„±ν•˜μ‹­μ‹œμ˜€. 그게 λ‹€μ•Ό!

react-redux-router λŠ” λΌμš°ν„° μΈμŠ€ν„΄μŠ€μ— μžλ™μœΌλ‘œ μ—°κ²°λœ μ €μž₯μ†Œμ—μ„œ μž‘μ—…μ„ μ „λ‹¬ν•˜κ³  μƒνƒœλ₯Ό 읽을 수 μžˆμ§€λ§Œ μ‚¬μš©ν•  ν•„μš”κ°€ μ—†λŠ” 보닀 μžμ—°μŠ€λŸ¬μš΄ APIλ₯Ό λ§Œλ“€λ €λŠ” μ‹€ν—˜μž…λ‹ˆλ‹€. λ˜λŠ” μ•ˆμ •ν™” 될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦¬μ‹­μ‹œμ˜€! μ‹€ν—˜μΌ λΏμž…λ‹ˆλ‹€.

μš°λ¦¬λŠ” λ¬Έμ„œμ—μ„œ 이것이 ν•„μš”ν•©λ‹ˆλ‹€..

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ˜ν•œ, λ¦¬μ•‘νŠΈ λΌμš°ν„°κ°€ 보편적으둜 μ‚¬μš©λ˜λŠ” 예λ₯Ό μΆ”κ°€ν•˜λŠ” 것에 λŒ€ν•΄ μ–΄λ–»κ²Œ μƒκ°ν•˜μ‹­λ‹ˆκΉŒ?

λͺ¨λ“  61 λŒ“κΈ€

λ‚˜λŠ” μ›λž˜ λ²”μš© μ»¨ν…μŠ€νŠΈμ—μ„œ λ°˜μ‘ λΌμš°ν„°λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ μ„œλ²„ μΈ‘ λ Œλ”λ§ 예제λ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€. λ°˜μ‘ λΌμš°ν„°μ™€ ν•¨κ»˜ μ‚¬μš©ν•˜λ©΄ 자체 λ¬Έμ„œκ°€ 될 수 μžˆλ‹€κ³  μ œμ•ˆλ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ¬Έμ„œμ— μ„Ήμ…˜μ„ μΆ”κ°€ν•  수 μžˆμ„κΉŒμš”?

λ˜ν•œ, λ¦¬μ•‘νŠΈ λΌμš°ν„°κ°€ 보편적으둜 μ‚¬μš©λ˜λŠ” 예λ₯Ό μΆ”κ°€ν•˜λŠ” 것에 λŒ€ν•΄ μ–΄λ–»κ²Œ μƒκ°ν•˜μ‹­λ‹ˆκΉŒ?

real-world 예제λ₯Ό 보편적으둜 μˆ˜μ •ν•˜λŠ” 것이 쒋은 생각이라고 μƒκ°ν•©λ‹ˆλ‹€. κ·Έλ ‡κ²Œ ν•˜λ©΄ μ²˜μŒλΆ€ν„° 아무것도 λ§Œλ“€ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

μ•‘μ…˜ μƒμ„±μžμ—μ„œ μ „ν™˜ν•˜λ €λ©΄ λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μ•‘μ…˜ μƒμ„±μžμ—κ²Œ λ§€κ°œλ³€μˆ˜λ‘œ μ „λ‹¬ν•˜μ‹­μ‹œμ˜€.

1.0betaμ—λŠ” createRouter κ°œλ…(아직?)이 μ—†κΈ° λ•Œλ¬Έμ— 이것은 0.13μ—μ„œλ§Œ μž‘λ™ν•©λ‹ˆλ‹€. λ§žμŠ΅λ‹ˆκΉŒ?

React ꡬ성 μš”μ†Œ λ‚΄μ—μ„œ 1.0.0-beta3으둜 μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

class Thing extends Component {
  static contextTypes = {
    router: PropTypes.object
  }

  handleThing() {
    this.props.actionCreator(this.context.router);
  }
}

@timdorr this.context λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ•ˆμ „ν•©λ‹ˆκΉŒ? λ‚˜λŠ” 그것이 μ™ΈλΆ€μ—μ„œ μ‚¬μš©λ˜λŠ” 것이 μ•„λ‹ˆλΌλŠ” 인상을 λ°›μ•˜μŠ΅λ‹ˆλ‹€.

예, μ•ˆμ „ν•˜μ§€ μ•Šμ€ 것이 μ•„λ‹ˆλΌ λ¬Έμ„œν™”λ˜μ§€ μ•Šμ€ κ²ƒμž…λ‹ˆλ‹€. 0.14μ—μ„œ μ•½κ°„ λ³€κ²½λ˜μ§€λ§Œ 이λ₯Ό κΉ¨λŠ” 방식은 μ•„λ‹™λ‹ˆλ‹€. λ‚˜λŠ” 그것이 곧 μ–΄λ–€ μ‹œμ μ—μ„œ λ¬Έμ„œν™”λ  것이라고 μƒκ°ν•©λ‹ˆλ‹€.

@timdorr 1.0.0-beta3μ—μ„œ μ•‘μ…˜ μƒμ„±μžμ™€ λ‹€λ₯Έ URL둜 μ „ν™˜ν•  μˆ˜λ„ μžˆλ‹€λŠ” λœ»μΈκ°€μš”?

예, λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μž‘μ—… μƒμ„±μžμ—κ²Œ μ „λ‹¬ν•˜λ©΄ μ „ν™˜μ„ ν¬ν•¨ν•˜μ—¬ μ›ν•˜λŠ” λͺ¨λ“  μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 ν•¨κ»˜ λ˜μ‘Œλ‹€ :

const loginProps = {
  handleLogin: ({email, password}) => store.dispatch(userLogin({email, password})),
};



const routes = (
  <Route path="/" handler={App}>
    <Route path="login" handler={wrapper(Login, loginProps)} />
    <Route handler={authSection}>
      <Route path="" handler={Index} />
      <Route path="users" handler={wrapper(Users, (() => store.dispatch(getUsers())))} />
      <Route path="logout" handler={wrapper(Login, (() => store.dispatch(userLogout())))} />
    </Route>
  </Route>
);

const router = createRouter({
  location: HistoryLocation,
  routes,
});

store.dispatch(receiveRouter({router}));

Warning: Failed Context Types: Required context `store` was not specified in `SmartComponent(TodoApp)`. Check the render method of `Router`.

무엇이 잘λͺ»λ˜μ—ˆμ„ 수 μžˆμŠ΅λ‹ˆκΉŒ?

μΆ”μ‹ : RR 1.0.0-베타3

@gyzerok real-world μ˜ˆμ œκ°€ ν•˜λŠ” κ²ƒμ²˜λŸΌ 전체 () => <Router>stuff</Router> λ₯Ό <Provider> $ 둜 감싸야 ν•©λ‹ˆλ‹€.

@gaearon λ„€, ofc. λ‚˜λŠ” 그것을 κ³΅κΈ‰μžκ°€ μ•„λ‹ˆλΌ λŒ€λΆ€λΆ„ λ‹Ήμ‹ μ˜ κ³΅κΈ‰μžμ˜ 볡사-뢙여넣기인 λ‚΄ μžμ‹ μ˜ κ΅¬μ„±μš”μ†Œμ— 포μž₯ν•©λ‹ˆλ‹€. 차이점은 μŠ€ν† μ–΄λ₯Ό μ „λ‹¬ν•˜μ§€ μ•Šκ³  κ·Έ μ•ˆμ— μŠ€ν† μ–΄λ₯Ό μƒμ„±ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

@gyzerok μ½”λ“œλ₯Ό 보지 μ•Šκ³ λŠ” 무엇이 잘λͺ»λ˜μ—ˆλŠ”지 λ§ν•˜κΈ° μ–΄λ ΅μŠ΅λ‹ˆλ‹€. (그리고 λ³„λ„μ˜ 호λ₯Ό μ œμΆœν•΄ μ£Όμ„Έμš”. react-redux repoκ°€ ​​쒋은 κ³³μž…λ‹ˆλ‹€.)

real-wolrd 에 λŒ€ν•œ Thx 예! κ·ΈλŸ¬λ‚˜ AsyncProps λŠ” μ–΄λ–»κ²Œ μ²˜λ¦¬ν•©λ‹ˆκΉŒ? 이쀑 μ»¨ν…μŠ€νŠΈ μ‘°μž‘μ΄ ν•¨κ»˜ μž‘λ™ν•˜μ§€ μ•ŠλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

import React from 'react';                                                                                                                                                                                         
import {createStore} from 'redux';                                                                                                                                                                                 
import {Provider} from 'react-redux';                                                                                                                                                                              
import {Router, Route} from 'react-router';                                                                                                                                                                        
import BrowserHistory from 'react-router/lib/BrowserHistory';                                                                                                                                                      
import AsyncProps from 'react-router/lib/experimental/AsyncProps';                                                                                                                                                 

import App from './containers/App';                                                                                                                                                                                
import reducers from './reducers';                                                                                                                                                                                 

const store = createStoreWithMiddleware(reducers);                                                                                                                                                                 
const history = new BrowserHistory();                                                                                                                                                                               

React.render(                                                                                                                                                                                                       
    <Provider store={store}>                                                                                                                                                                                        
        {() =>                                                                                                                                                                                                      
            <Router history={history} createElement={AsyncProps.createElement}>                                                                                                                                     
                <Route component={AsyncProps}>                                                                                                                                                                      
                    <Route path="/" component={App} />                                                                                                                                                              
                </Route>                                                                                                                                                                                            
            </Router>                                                                                                                                                                                               
        }                                                                                                                                                                                                           
    </Provider>,                                                                                                                                                                                                    
    document.body                                                                                                                                                                                                  
);

그리고 App.js

import React from 'react';                                                                                                                                                                                         
import {connect} from 'react-redux';                                                                                                                                                                               

let App = React.createClass({                                                                                                                                                                                      
    statics: {                                                                                                                                                                                                     
        loadProps(params, cb) {                                                                                                                                                                                    
            // have to call this with AsyncProps                                                                                                                                                                   
        }                                                                                                                                                                                                          
    },                                                                                                                                                                                                             
    displayName: 'App',                                                                                                                                                                                            

    render() {                                                                                                                                                                                                     
        return <div children="this is app" />                                                                                                                                                                      
    }                                                                                                                                                                                                              
});                                                                                                                                                                                                                

export default connect(state => state)(App); 

connect 래퍼 없이도 μž‘λ™ν•˜μ§€λ§Œ redux 도 μ—†μŠ΅λ‹ˆλ‹€. λˆ„κ΅¬λ“ μ§€μ΄ λ¬Έμ œμ— 직면 ν–ˆμŠ΅λ‹ˆκΉŒ?

μ•„λ‹ˆλ©΄ 데이터가 λ‘œλ“œλ  λ•ŒκΉŒμ§€ 탐색을 μΌμ‹œ μ€‘μ§€ν•˜λŠ” λ‹€λ₯Έ 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

μŠ€νƒœν‹±μ€ μŠ€νƒœν‹±μΌ λΏμž…λ‹ˆλ‹€. connect() κ²°κ³Όλ₯Ό ν¬ν•¨ν•˜μ—¬ 무엇이든 넣을 수 μžˆμŠ΅λ‹ˆλ‹€.

let App = React.createClass({                                                                                                                                                                                      
    displayName: 'App',                                                                                                                                                                                            

    render() {                                                                                                                                                                                                     
        return <div children="this is app" />                                                                                                                                                                      
    }                                                                                                                                                                                                              
});                                                                                                                                                                                                                

App = connect(state => state)(App); 

App.loadProps = function loadProps(params, cb) {                                                                                                                                                                                    
  // have to call this with AsyncProps                                                                                                                                                                   
}                                                                                                                                                                                                          

export default App; 

@gaearon μ£„μ†‘ν•©λ‹ˆλ‹€. μ˜ˆμ‹œκ°€ λΆ€μ‘±ν•©λ‹ˆλ‹€. 정적 μ†Œν’ˆμ΄ λˆ„λ½λ˜μ–΄ connect κ²°κ³Όλ₯Ό ν™•μž₯ν•˜λ €κ³  μ‹œλ„ν–ˆμ§€λ§Œ μ»¨ν…μŠ€νŠΈμ— μ‹€μ œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ‹œκ°„μ„ μ£Όμ„Έμš”. 전체 예제λ₯Ό λ³„λ„μ˜ μ €μž₯μ†Œλ‘œ ν‘Έμ‹œν•˜κ² μŠ΅λ‹ˆλ‹€.

λ‚΄κ°€ ν˜„μž¬ μ‘°μ‚¬ν•˜κ³  μžˆλŠ” 또 λ‹€λ₯Έ 것은 λͺ…ν™•ν•˜κ³  λˆˆμ— κ±°μŠ¬λ¦¬μ§€ μ•ŠλŠ” λ°©μ‹μœΌλ‘œ redux μ €μž₯μ†Œμ— paramsλ₯Ό μ €μž₯ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λͺ‡ 가지 μ ‘κ·Ό 방식을 μ‹œλ„ν•œ ν›„ λ‹€μŒκ³Ό 같이 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

<Route
  component={OrderDetails}
  path='/orders/:orderId'
  onEnter={({params}) => store.dispatch(setCurrentOrder(params.orderId))} 
/>

λ”°λΌμ„œ μ•„λž˜μ™€ 같이 μ„ νƒκΈ°μ—μ„œ λ§€κ°œλ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

export const OrderDetails = state => {
  const {order} = state;
  return {
    order: order.details.get(order.currentOrderId),
    orderId: order.currentOrderId,
    isLoading: order.isLoadingDetails,
    error: order.detailsLoadingError
  };
};

μ•ˆμ •μ μΈ react-redux-router κ°€ μΆœμ‹œλ˜λ©΄ μ•„λ§ˆ λ°”λ€” κ²ƒμž…λ‹ˆλ‹€.

쒋은 μ†Œμ‹: React Router 1.0 RCλŠ” 이제 μš°λ¦¬κ°€ ν•„μš”λ‘œ ν•˜λŠ” 후크λ₯Ό λ…ΈμΆœν•©λ‹ˆλ‹€.
https://github.com/acdlite/redux-react-router λ₯Ό ν™•μΈν•˜κ³  μ§€κΈˆ λ§ˆμŒμ— λ“œλŠ”μ§€ μ•Œλ €μ£Όμ„Έμš”!

@gaearon react-router 및 μ‹€ν—˜μ μΈ AsyncProps 문제λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. λ°˜μ‘μ„ μ—…λ°μ΄νŠΈν•˜λ©΄ λ¬Έμ œκ°€ ν•΄κ²°λ©λ‹ˆλ‹€.

@wtfil λ°˜κ°‘μŠ΅λ‹ˆλ‹€!

react-router와 톡합할 λ•Œ 이 μŠ€λ ˆλ“œμ—μ„œ λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μž‘μ—… μƒμ„±μžμ—κ²Œ μ „λ‹¬ν•˜κ³  이에 λŒ€ν•œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€λŠ” 것을 μ΄ν•΄ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ λ‚˜λŠ” λ˜ν•œ μ•‘μ…˜ μ œμž‘μžκ°€ κ°€μž₯ μˆœμˆ˜ν•œ ν˜•νƒœλ‘œ λΆ€μž‘μš©μ΄ 없도둝 μ˜λ„λ˜μ—ˆλ‹€λŠ” 것을 μ΄ν•΄ν•©λ‹ˆλ‹€. μ•‘μ…˜ μƒμ„±μžμ—κ²Œ λΆ€μž‘μš©μ΄ ν—ˆμš©λ˜λŠ” μœ μΌν•œ κ²½μš°λŠ” 미듀웨어가 μ²˜λ¦¬ν•˜λŠ” 비동기 μ•‘μ…˜μΌ λ•ŒλΏμž…λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ μ „ν™˜μ„ μˆ˜ν–‰ν•˜λŠ” μ•‘μ…˜ μƒμ„±μžκ°€ 순수 κΈ°λŠ₯이 μ•„λ‹ˆλΌ 비동기식이어야 ν•œλ‹€λŠ” κΈ°λŒ€κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

κ·Έλ ‡λ‹€λ©΄ μ „ν™˜μ„ μˆ˜ν–‰ν•˜λŠ” μ•‘μ…˜ μƒμ„±μžκ°€ 순수 κΈ°λŠ₯이 μ•„λ‹ˆλΌ 비동기식이어야 ν•œλ‹€λŠ” κΈ°λŒ€κ°€ μžˆμŠ΅λ‹ˆκΉŒ?

μ•‘μ…˜ μ œμž‘μžλŠ” λΆ€μž‘μš©μ΄ μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. κ°€λŠ₯ν•˜λ©΄ ν”Όν•˜λŠ” 것이 κ°€μž₯ μ’‹μ§€λ§Œ λ¬Όλ‘  μ–΄λŠ μ‹œμ μ—λŠ” ν•„μš”ν•©λ‹ˆλ‹€. λ¦¬λ“€μ„œλŠ” Reduxμ—μ„œ μˆœμˆ˜ν•˜κ³  Elmκ³Ό 같은 λͺ…μ‹œμ  효과 λ©”μ»€λ‹ˆμ¦˜μ΄ μ—†κΈ° λ•Œλ¬Έμ—(토둠은 #569 μ°Έμ‘°) μ•‘μ…˜ μƒμ„±μžλŠ” λ„£μ–΄λ‘λŠ” κ³³.

redux-router λ₯Ό ν™•μΈν•˜μ‹­μ‹œμ˜€. React Router μœ„μ—μ„œ μž‘λ™ν•˜μ§€λ§Œ μž‘μ—…μ„ λ””μŠ€νŒ¨μΉ˜ν•˜κ³  λΌμš°ν„° 동기화λ₯Ό μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

React Router와 Redux Routerκ°€ λͺ¨λ‘ 1.0에 λ„λ‹¬ν•˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” 쀑...

λ„€. 이 일이 λ°œμƒν•œ ν›„ λ ˆμ‹œν”Όλ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

κ·Έλž˜μ„œ μ €λŠ” 이 토둠을 따라가며 λΌμš°νŒ…μ΄ 일반적으둜 redux에 μ–΄λ–»κ²Œ μ μš©λ˜λŠ”μ§€μ— λŒ€ν•΄ 쑰금 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€(https://github.com/rackt/redux/issues/805 μ°Έμ‘°). ν•΄λ‹Ή μŠ€λ ˆλ“œμ˜ 일뢀 ν† λ‘ κ³Ό 일뢀 μ‹€ν—˜μ„ 기반으둜 개인적으둜 react-router/react-redux-router 글루보닀 μ„ ν˜Έν•˜λŠ” μ ‘κ·Ό 방식을 μ°Ύμ•˜μŠ΅λ‹ˆλ‹€.

기본적으둜 react-router λ˜λŠ” redux에 μ„œλ‘œμ— λŒ€ν•œ 정보λ₯Ό μ œκ³΅ν•˜μ§€ μ•Šκ³  λŒ€μ‹  μ‚¬μš©μž 지정 기둝 κ΅¬ν˜„μ„ 톡해 μ—°κ²°ν•˜λ €κ³  ν•©λ‹ˆλ‹€. 이 μ ‘κ·Ό 방식을 μ‚¬μš©ν•˜λ©΄ λΌμš°νŒ…μ΄ λ‹€μŒκ³Ό 같이 μ²˜λ¦¬λ©λ‹ˆλ‹€.

  1. route 에 λŒ€ν•œ μž‘μ—…, 감속기 및 μ €μž₯μ†Œμ˜ ν‚€κ°€ μƒμ„±λ©λ‹ˆλ‹€.
  2. ν‘œμ€€ 기둝 κ΅¬ν˜„(이 μ˜ˆμ œμ—μ„œλŠ” μ„ ν˜Έν•˜λŠ” createHistory 을 μ‚¬μš©ν•˜μ§€λ§Œ createHashHistory λ˜λŠ” 무엇이든 μ‰½κ²Œ μ‚¬μš©ν•  수 있음)이 μƒμ„±λ˜κ³  μˆ˜μ‹ λ©λ‹ˆλ‹€. λΈŒλΌμš°μ €μ˜ ν˜„μž¬ μœ„μΉ˜κ°€ λ³€κ²½λ˜λ©΄ ROUTE μž‘μ—…μ΄ μ „λ‹¬λ˜μ–΄ ꢁ극적으둜 ν•΄λ‹Ή μœ„μΉ˜λ₯Ό 상점에 λ°°μΉ˜ν•©λ‹ˆλ‹€.
  3. ν‘œμ€€ react-router μΈμŠ€ν„΄μŠ€λŠ” μ €μž₯μ†Œμ˜ route ν‚€κ°€ 변경될 λ•Œ κ΅¬λ…μž(react-router)μ—κ²Œ μ•Œλ¦¬λŠ” 두 번째 μ‚¬μš©μž 지정 기둝 κ΅¬ν˜„μœΌλ‘œ μƒμ„±λ©λ‹ˆλ‹€. λ˜ν•œ createHref 및 pushState λ₯Ό μ •μ˜ν•˜κ³  λ‘˜ λ‹€ 2λ‹¨κ³„μ—μ„œ μƒμ„±λœ ν‘œμ€€ 기둝에 μœ„μž„ν•©λ‹ˆλ‹€.

그게 λ‹€μ•Ό λ‚˜λŠ” 그것이 redux와 react-router 사이에 μƒλ‹Ήνžˆ λͺ…ν™•ν•œ 업무 뢄리λ₯Ό μ œκ³΅ν•˜κ³  λ‹€λ₯Έ "μ ‘μ°©μ œ" 라이브러리λ₯Ό κ°€μ Έμ˜¬ ν•„μš”κ°€ μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. μ•„λž˜μ— λ‚΄ μ½”λ“œλ₯Ό λΆ™μ—¬λ„£κ³  μžˆμŠ΅λ‹ˆλ‹€. ν”Όλ“œλ°±μ„ λ“£κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

// please pay attention to library versions, this strategy is only tested with the indicated versions
import React from 'react'; // v0.13.3
import { Provider } from 'react-redux'; // v3.1.0
import { Router, Route, IndexRoute, Link } from 'react-router'; // v1.0.0-rc3
import { createHistory } from 'history'; // v1.12.3
import { createStore } from 'redux'; // v3.0.2

// define some components
class About extends React.Component {
    render () {
        return (
            <div><h1>About</h1></div>
        )
    }
}
class Home extends React.Component {
    render () {
        return (
            <div>
                <h1>Home</h1>
                <Link to="/about">Go to about</Link>
            </div>
        )
    }
}

// create a standard history object
var history = createHistory();

// set up 'route' action and action creator
const ROUTE = 'ROUTE';
function createRouteAction (location) {
    return {
        type: ROUTE,
        payload: location
    };
}

// set up reducer. here we only define behavior for the route action
function reducer (state = {}, action) {
    if (action.type === ROUTE) {
        return Object.assign({}, state, {
            route: action.payload
        });
    }
    else {
        return state;
        // whatever other logic you need
    }
}

// create store
const store = createStore(reducer);

// this factory returns a history implementation which reads the current state
// from the redux store and delegates push state to a different history.
function createStoreHistory () {
    return {
        listen: function (callback) {
            // subscribe to the redux store. when `route` changes, notify the listener
            const unsubscribe = store.subscribe(function () {
                const route = store.getState().route;
                callback(route);
            });

            return unsubscribe;
        },
        createHref: history.createHref,
        pushState: history.pushState
    }
}

React.render(
    <Provider store={store}>
        {() =>
            <Router history={createStoreHistory()}>
                <Route path="/about" component={About} />
                <Route path="/" component={Home} />
            </Router>
        }
    </Provider>,
    document.getElementById('root') // or whatever
);

// when the url changes, dispatch a route action. this is placed at the bottom so that the first route triggers the initial render
const unlisten = history.listen(function (location) {
    store.dispatch(createRouteAction(location));
});

그건 κ·Έλ ‡κ³ , 이 μ˜ˆκ°€ redux와 react-routerλ₯Ό ν•¨κ»˜ μ‚¬μš©ν•˜λŠ” 데 어렀움을 κ²ͺκ³  μžˆλŠ” λ‚˜μ™€ 같은 μ‚¬λžŒλ“€μ—κ²Œ 도움이 될 수 있고 였늘 redux와 react-routerλ₯Ό ν•¨κ»˜ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” μ£Όμž₯을 λͺ…ν™•νžˆ ν•˜λŠ” 데 도움이 될 수 있기 λ•Œλ¬Έμ— 이 예λ₯Ό μ–ΈκΈ‰ν•©λ‹ˆλ‹€.

@cappslock λ‚˜λŠ” 그것을 μ’‹μ•„ν•˜μ§€λ§Œ ν•œ 가지 μž‘μ€ 것이 μžˆμŠ΅λ‹ˆλ‹€. κ·€ν•˜μ˜ κ΅¬ν˜„μ—μ„œ 경둜 변경은 μž‘μ—…μž…λ‹ˆλ‹€. 이것은 "μž‘μ—…μ€ λͺ…령이 μ•„λ‹Œ 이벀트" μ ‘κ·Ό 방식을 κΉ¨κ³  κ²°κ΅­ 일뢀 λΆˆμΎŒν•œ κ΄€ν–‰μœΌλ‘œ μ΄μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. 생각을 λ°”κΏ”λ³΄μž. 잠재적으둜 λͺ¨λ“  μž‘μ—…μ€ μ£Όμ†Œ ν‘œμ‹œμ€„(ꡬ성 μš”μ†Œ λ˜λŠ” μ‹€μ œ λΈŒλΌμš°μ €μ˜ μ£Όμ†Œ ν‘œμ‹œμ€„....)을 λ³€κ²½ν•˜λŠ” λΆ€μž‘μš©μ„ μ΄ˆλž˜ν•  수 있고 λΆ€μž‘μš©μœΌλ‘œ 인해 μƒˆ μž‘μ—…( ROUTE_CHANGED )이 λ°œμ†‘λ  수 μžˆμŠ΅λ‹ˆλ‹€. API ν˜ΈμΆœμ„ νŠΈλ¦¬κ±°ν•˜λŠ” 것과 기본적으둜 λ™μΌν•œ νŒ¨ν„΄μž…λ‹ˆλ‹€.

@tomkis1 ν”Όλ“œλ°± μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. λ‚΄κ°€ 당신을 μ˜¬λ°”λ₯΄κ²Œ μ΄ν•΄ν•œλ‹€λ©΄ 이것은 μ‹€μ œλ‘œ 이미 κ·Έλ ‡κ²Œ μž‘λ™ν•©λ‹ˆλ‹€. ROUTE μ•‘μ…˜μ€ URL λ³€κ²½μ˜ λΆ€μž‘μš©μœΌλ‘œ μ „λ‹¬λ©λ‹ˆλ‹€. ROUTE_CHANGED κ°€ 더 λ‚˜μ€ 이름이 λ κΉŒμš”?

였! 방금 두 번 ν™•μΈν–ˆκ³  당신이 μ˜³μ•˜μŠ΅λ‹ˆλ‹€. 예 ROUTE_CHANGED κ°€ 더 쒋을 κ²ƒμž…λ‹ˆλ‹€.

λ‚˜λ„ κ·Έλ ‡κ²Œ 생각해. λ‹€μ‹œ λŒμ•„κ°€μ„œ λ³€κ²½ν•˜κ² μ§€λ§Œ 이 λŒ“κΈ€μ€ 정말 ν˜Όλž€μŠ€λŸ¬μšΈ κ²ƒμž…λ‹ˆλ‹€. :)

흐름은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

URL λ³€κ²½ -> ROUTE (λ˜λŠ” ROUTE_CHANGED ) μž‘μ—… -> λ¦¬λ“€μ„œ μ—…λ°μ΄νŠΈ μ €μž₯μ†Œ -> μ €μž₯μ†Œ 기둝(이전에 μ €μž₯μ†Œμ— κ°€μž…λ¨) λ¦¬μŠ€λ„ˆμ— μ•Œλ¦Ό -> λ°˜μ‘ λΌμš°ν„° μ—…λ°μ΄νŠΈ

λ‚˜λŠ” UI의 μ‚¬μš©μž κ΄€μ°° μƒνƒœλ₯Ό κ΅¬λ™ν•˜λŠ” 상점 μ™Έμ—λŠ” 아무것도 μ›ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 이것을 μ„ ν˜Έν•©λ‹ˆλ‹€. ν…ŒμŠ€νŠΈμš©μœΌλ‘œλ„ 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

이 μ ‘κ·Ό λ°©μ‹μ˜ 단점은 URL이 ROUTE_CHANGED μž‘μ—…μ— λŒ€ν•œ μ‘λ‹΅μœΌλ‘œ μ—…λ°μ΄νŠΈλ˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ•‘μ…˜μ΄ λͺ…λ ΉμœΌλ‘œ μ²˜λ¦¬λ˜λŠ” 것을 μ›ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 이것이 λ°”λžŒμ§ν•œμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ ROUTE_CHANGED μ•‘μ…˜ μƒμ„±μžμ˜ λΆ€μž‘μš©μœΌλ‘œ λ˜λŠ” λ³„λ„μ˜ 상점 κ°€μž…μž.

BTW, 이 λ…Όμ˜κ°€ 이 문제의 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜λŠ” 경우 μ•Œλ €μ£Όμ‹œλ©΄ μ΄λ™ν•˜κ² μŠ΅λ‹ˆλ‹€.

@cappslock λ„ˆλ¬΄ μ’‹μ•„μš”! ROUTE_CHANGED λ₯Ό λ°œμ†‘ν•œλ‹€κ³  ν•΄μ„œ κ²½λ‘œκ°€ λ°”λ€Œμ§€ μ•ŠλŠ” 것은 ν™•μ‹€νžˆ λ¬Έμ œκ°€ μ•„λ‹ˆλΌκ³  μƒκ°ν•©λ‹ˆλ‹€. μ•‘μ…˜μ„ νŠΈλ¦¬κ±°κ°€ μ•„λ‹Œ 이벀트둜 μ²˜λ¦¬ν•˜λŠ” 것이 더 λͺ…ν™•ν•˜κ³  μ΄ν•΄ν•˜κΈ° μ‰¬μš΄ 것 κ°™μŠ΅λ‹ˆλ‹€(μ‚¬μš©μž μƒν˜Έ μž‘μš©μ— μ‘λ‹΅ν•˜κΈ° λ•Œλ¬Έμ— BUTTON_CLICKED μ•‘μ…˜μ΄ μ‹€μ œλ‘œ λ²„νŠΌ 클릭을 νŠΈλ¦¬κ±°ν•  κ²ƒμœΌλ‘œ κΈ°λŒ€ν•˜μ§€ μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€). λ‚΄κ°€ μ΄ν•΄ν•˜μ§€ λͺ»ν•˜λŠ” μ½”λ“œμ˜ ν•œ 뢀뢄이 μžˆμŠ΅λ‹ˆλ‹€. 이 뢀뢄에 λŒ€ν•΄ μžμ„Ένžˆ μ„€λͺ…ν•΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ?

이것은 첫 번째 κ²½λ‘œκ°€ 초기 λ Œλ”λ§μ„ νŠΈλ¦¬κ±°ν•˜λ„λ‘ 맨 μ•„λž˜μ— λ°°μΉ˜λ©λ‹ˆλ‹€.

@elliotdickison κ°μ‚¬ν•©λ‹ˆλ‹€! λΆ„λͺ…νžˆ λ§μ”€λ“œλ¦¬κ² μ§€λ§Œ 깊이 μžˆλŠ” 뢄석이 μ•„λ‹Œ μ‹œν–‰μ°©μ˜€μ™€ 가정을 λ°”νƒ•μœΌλ‘œ ν•˜λŠ” λ§μ”€μ΄λ‹ˆ λƒ‰μ •ν•˜κ²Œ λ°›μ•„λ“€μ΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€. 이것은 이 μ‹œμ μ—μ„œ κ°œλ…/μŠ€μΌ€μΉ˜μ˜ 증λͺ…에 κ°€κΉμŠ΅λ‹ˆλ‹€.

ReactRouter 의 μΈμŠ€ν„΄μŠ€ν™” μœ„μ— ν•΄λ‹Ή μ½”λ“œλ₯Ό λ°°μΉ˜ν–ˆμ„ λ•Œ / κ²½λ‘œμ— ν•΄λ‹Ήν•˜λŠ” ꡬ성 μš”μ†ŒλŠ” λ Œλ”λ§λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. μž‘μ—…μ΄ μˆ˜λ™μœΌλ‘œ λ””μŠ€νŒ¨μΉ˜λ˜κ±°λ‚˜ μƒνƒœκ°€ μˆ˜λ™μœΌλ‘œ ν‘Έμ‹œλœ 경우 λΌμš°ν„°κ°€ 계속 μž‘λ™ν•˜λ―€λ‘œ νžˆμŠ€ν† λ¦¬μ˜ 수λͺ… μ£ΌκΈ° 문제라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€. ReactRouter 의 μΈμŠ€ν„΄μŠ€ν™” μ•„λž˜λ‘œ μ΄λ™ν•˜λ©΄ 이 λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” νžˆμŠ€ν† λ¦¬ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 적어도 ν•œ λͺ…μ˜ κ΅¬λ…μžκ°€ μžˆμ„ λ•ŒκΉŒμ§€ 초기 경둜의 μ•Œλ¦Όμ„ μ—°κΈ°ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. ν•΄λ‹Ή κ΅¬λ…μžκ°€ ReactRouter보닀 λ¨Όμ € μ„€μ •λ˜λ©΄ μ•Œλ¦Όμ΄ λ„λ‹¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

이것을 μ„€λͺ…ν•˜λ €κ³  ν•˜λ©΄ λ‚΄ 이해가 μ•½κ°„ λΆ€μ‘±ν•˜λ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€. 이에 λŒ€ν•΄ 더 μ•Œμ•„λ³΄κ³  더 λ‚˜μ€ 닡변을 λ“œλ¦΄ 수 μžˆλ„λ‘ λ…Έλ ₯ν•˜κ² μŠ΅λ‹ˆλ‹€.

이 μ ‘κ·Ό λ°©μ‹μ˜ 단점은 ROUTE_CHANGED μž‘μ—…μ— λŒ€ν•œ μ‘λ‹΅μœΌλ‘œ URL이 μ—…λ°μ΄νŠΈλ˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μž‘μ—…μ„ λͺ…λ ΉμœΌλ‘œ μ²˜λ¦¬ν•˜μ§€ μ•ŠμœΌλ €λŠ” 경우 이것이 λ°”λžŒμ§ν•œμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ ROUTE_CHANGED μž‘μ—… μƒμ„±μžμ˜ λΆ€μž‘μš©μœΌλ‘œ λ˜λŠ” λ³„λ„μ˜ μŠ€ν† μ–΄ κ΅¬λ…μžκ°€ μ™„λ£Œν•  수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

λ‚˜λŠ” 이것이 λ°”λžŒμ§ν•˜λ‹€κ³  λ§ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. ROUTE_CHANGED λŠ” ν™•μ‹€νžˆ μ™ΈλΆ€ μ†ŒμŠ€(예: onhashchange...)에 μ˜ν•΄ μ‹€ν–‰λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. IMO URL 변경은 κ·Έ λ°˜λŒ€κ°€ μ•„λ‹ˆλΌ ROUTE_CHANGED 이 λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

λ™μ˜ν•©λ‹ˆλ‹€. λ””μŠ€νŒ¨μΉ˜λœ ROUTE_CHANGED μ•‘μ…˜μ΄ μ‹€μ œ νžˆμŠ€ν† λ¦¬ μ΄λ²€νŠΈκ°€ μ•„λ‹Œ μ½”λ“œμ—μ„œ μ‹œμž‘λœ 경우λ₯Ό λŒ€λΉ„ν•˜μ—¬ μŠ€ν† μ–΄λ₯Ό κ΅¬λ…ν•˜κ³  URL을 λ™κΈ°ν™”λœ μƒνƒœλ‘œ μœ μ§€ν•˜λŠ” 것이 쒋을 것이라고 μƒκ°ν–ˆμ§€λ§Œ κ·Έ κ²½μš°κ°€ λ‹€μŒμ„ λ‚˜νƒ€λ‚Έλ‹€κ³  μ£Όμž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν”„λ‘œκ·Έλž˜λ° 였λ₯˜.

@cappslock λ‹Ήμ‹ μ˜ μ ‘κ·Ό 방식은 정말 정말 μ’‹μŠ΅λ‹ˆλ‹€. 그것에 λŒ€ν•΄ λΈ”λ‘œκ·Έ 포슀트λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆκΉŒ?

@vojtatranta https://github.com/rackt/redux/issues/805 λ₯Ό ν™•μΈν•˜μ‹­μ‹œμ˜€. κ΅¬ν˜„μ— μ˜κ°μ„ μ€€ 것 κ°™μŠ΅λ‹ˆλ‹€.

@vojtatranta κ°μ‚¬ν•©λ‹ˆλ‹€! λ‚˜λŠ” λΈ”λ‘œκ·Έκ°€ μ—†κΈ° λ•Œλ¬Έμ— 거의 λͺ¨λ“  정보가 이 μŠ€λ ˆλ“œμ™€ #805에 μžˆμŠ΅λ‹ˆλ‹€. 특히 더 λ§Žμ€ 정보λ₯Ό μ›ν•˜μ…¨λ‚˜μš”?

1.0이 λ‚˜μ™”μŠ΅λ‹ˆλ‹€.

λ‹€μŒμ„ μˆ˜ν–‰ν•  μ‹œκ°„μž…λ‹ˆλ‹€.

  • μ‚¬μš©ν•˜λŠ” 포트 λΌμš°νŒ… 예제
  • real-world 예제λ₯Ό 기반으둜 "λΌμš°ν„° μ‚¬μš©" λ ˆμ‹œν”Ό μΆ”κ°€

:λ°•μˆ˜:

@gaearon _Usage with Router_ μ˜ˆμ œκ°€ PR에 μžˆμ„ λ•Œ 이 문제λ₯Ό μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? λ‚΄κ°€ μ•„λŠ” λ§Žμ€ μ‚¬λžŒλ“€(μ €λ₯Ό ν¬ν•¨ν•˜μ—¬)은 이 두 가지가 μ–΄λ–»κ²Œ ν•¨κ»˜ 잘 μž‘λ™ν•˜λŠ”μ§€μ— λŒ€ν•œ μ„€λͺ…을 μ°Ύκ³  μžˆμŠ΅λ‹ˆλ‹€.

물둠이지. λ¬Έμ œκ°€ μ’…λ£Œλ˜λŠ” μ‹œμ μž…λ‹ˆλ‹€. :-)

이제 redux-simple-router λ₯Ό κ³ λ €ν•΄μ•Ό ν• κΉŒμš”?

redux-simple-router +1

방금 λ²”μš© 예제 + react-router(+redux-simple-router)λ₯Ό λ³€ν™˜ν–ˆμŠ΅λ‹ˆλ‹€.
https://github.com/eriknyk/redux-universal-app

μ•ˆλ…• μ—¬λŸ¬λΆ„, 이 ν† λ‘ μ˜ 결둠은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? λ‚˜λŠ” λ¬Έμ„œκ°€ react-router와 ν•¨κ»˜ μ‚¬μš©ν•˜λ„λ‘ μ—…λ°μ΄νŠΈλ˜μ§€ μ•Šμ€ 것을 λ΄…λ‹ˆλ‹€.
cc @gaearon

@gaearon λ‚΄ λ°˜μ‘ μ‘μš© ν”„λ‘œκ·Έλž¨μ„ redux에 λ°”μΈλ”©ν•œ ν›„ μƒνƒœλ₯Ό μ‚¬μš©ν•˜μ—¬ ꡬ성 μš”μ†Œμ˜ ν‘œμ‹œ/μˆ¨κΉ€μ„ μ œμ–΄ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ μ €λŠ” RRκ³Ό 같은 μ›λž˜μ˜ "λΌμš°ν„°" 역할이 μ§€κΈˆ 제 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— μ ν•©ν•˜μ§€ μ•Šλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.
"μƒˆ λΌμš°ν„°"κ°€ ν•΄μ•Ό ν•  일은 URL을 μƒνƒœμ— λ§€ν•‘ν•˜κ³ (λ™μž‘μ„ 톡해?) μƒνƒœλ₯Ό λ‹€μ‹œ url에 λ‹€μ‹œ λ§€ν•‘ν•˜λŠ” 것뿐이라고 μƒκ°ν•©λ‹ˆλ‹€.
url이 μ‘μš© ν”„λ‘œκ·Έλž¨ ꡬ성 μš”μ†Œ(κ·Έ 쀑 일뢀)κ°€ ν‘œμ‹œλ˜λŠ” 방법을 κ²°μ •ν•˜κ²Œ ν•˜λ©΄ μƒνƒœ μ†ŒμŠ€κ°€ 두 개 μžˆμŠ΅λ‹ˆλ‹€. ν•˜λ‚˜λŠ” url이고 λ‹€λ₯Έ ν•˜λ‚˜λŠ” redux의 μ €μž₯μ†Œμ΄λ―€λ‘œ 상황이 더 μ–΄λ €μ›Œμ§‘λ‹ˆλ‹€...
이에 λŒ€ν•΄ 뭐라고 ν•©λ‹ˆκΉŒ? μ£Όμ†Œ ν‘œμ‹œμ€„μ„ μ‘μš© ν”„λ‘œκ·Έλž¨ ꡬ성 μš”μ†Œμ˜ 또 λ‹€λ₯Έ ꡬ성 μš”μ†Œλ‘œ 두어야 ν•©λ‹ˆλ‹€.

감사 ν•΄μš”

https://github.com/rackt/react-router-redux/pull/259λ₯Ό μΆœμ‹œν•œ ν›„ κ³΅μ‹μ μœΌλ‘œ 이 λ¬Έμ„œλ₯Ό μž‘μ„±ν•  것을 μ•½μ†ν•©λ‹ˆλ‹€. 이것은 React Router와 Reduxλ₯Ό λ°”μΈλ”©ν•˜λŠ” μΆ•λ³΅λœ 방법이 될 κ²ƒμž…λ‹ˆλ‹€. λ¬Έμ„œμ—μ„œ λ¨Όμ € ν•΄λ‹Ή νŒ¨ν‚€μ§€ 없이 μ‚¬μš©ν•˜λŠ” 방법을 보여주고 νŒ¨ν‚€μ§€κ°€ μ œκ³΅ν•˜λŠ” 두 가지 νŽΈλ¦¬ν•¨μ„ μ μ§„μ μœΌλ‘œ μ†Œκ°œν•©λ‹ˆλ‹€. 미듀웨어와 λΌμš°νŒ… μ†ŒμŠ€λ₯Ό μ €μž₯μ†Œλ‘œ μ΄λ™ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‘˜ λ‹€ 선택 μ‚¬ν•­μ΄λ―€λ‘œ μ‚¬μš©ν•˜κΈ°λ‘œ μ„ νƒν•˜λŠ” κ²½μš°μ™€ κΈ°λ³Έ RR에 λŒ€ν•΄ μ œκ³΅ν•˜λŠ” 사항을 ν™•μ‹€νžˆ μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

여기에 κ³ λ €ν•΄μ•Ό ν•  생각이 μžˆμŠ΅λ‹ˆλ‹€. λΌμš°νŒ… 및 기둝과 κ΄€λ ¨λœ 미듀웨어에 λŒ€ν•΄ μ„€λͺ…ν•˜λŠ” 것이 http://rackt.org/redux/docs/advanced/Middleware.html 의 일반적인 μ„€λͺ… λ‚΄μ—μ„œ μ‹€μ œ μ‘μš© ν”„λ‘œκ·Έλž¨μ˜ νŠΉμ • 뢀뢄이 될 수 μžˆλŠ” 경우( 예λ₯Ό λ“€μ–΄ 끝에 μžˆλŠ” μ˜ˆμ œμ—μ„œ)

@gaearon React Router λ¬Έμ„œ/λ‹€μŒ 단계에 λŒ€ν•œ 진행 상황이 μžˆμŠ΅λ‹ˆκΉŒ? λ‚˜λŠ” Redux λ¬Έμ„œλ₯Ό 읽고 그것을 μ‚¬λž‘ν•˜μ§€λ§Œ κ·Έ κ°€μ§œ 링크에 μ˜ν•΄ λΆ€λ„λŸ¬μ›Œν•©λ‹ˆλ‹€ :(

λ‚˜λŠ” 단지 λ‚΄ 개인 repoμ—μ„œ react λΌμš°ν„° λ¬Έμ„œλ₯Ό λ‹€μ‹œ μž‘μ„±ν•˜κΈ° μ‹œμž‘ν–ˆκ³  거기에도 redux μ„Ήμ…˜μ„ κ°€μ§ˆ κ³„νšμž…λ‹ˆλ‹€. λ‚΄ 자유 μ‹œκ°„μ— 따라 곧 ν•  일이 μžˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 계속 μ—…λ°μ΄νŠΈν•˜κ² μŠ΅λ‹ˆλ‹€. https://github.com/knowbody/react-router-docs

κ³΅ν‰ν•˜κ²Œ λ°˜μ‘ λΌμš°ν„°κ°€ μž‘λ™ν•˜λ„λ‘ ν•˜κΈ° μœ„ν•΄ Redux μΈ‘μ—μ„œ 아무 것도 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ μš°λ¦¬λŠ” 이것을 ν•΄μ•Ό ν•©λ‹ˆλ‹€.

주의: React Router 3.0은 React Redux connect() μ΅œμ ν™”μ™€ 더 잘 μž‘λ™ν•˜λ©° μƒˆλ‘œμš΄ withRouter() HOCλŠ” μ»¨ν…μŠ€νŠΈλ₯Ό 직접 μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

https://twitter.com/dan_abramov/status/729768048417251328

@gaearon , @timdorr λΌμš°ν„° μΈμŠ€ν„΄μŠ€λ₯Ό μ•‘μ…˜ μƒμ„±μžμ— λŒ€ν•œ 인수둜 μ „λ‹¬ν•˜λŠ” 것과 μ•‘μ…˜ μƒμ„±μžμ—μ„œ browserHistoryλ₯Ό 직접 κ°€μ Έμ˜€λŠ” 것 μ‚¬μ΄μ˜ μ ˆμΆ©μ μ„ λͺ…ν™•νžˆ ν•  수 μžˆμŠ΅λ‹ˆκΉŒ(μ—¬κΈ°μ—μ„œ μ œμ•ˆλœ λŒ€λ‘œ https://github.com/reactjs/react-router/blob /master/docs/guides/NavigatingOutsideOfComponents.md?

router λŠ” 기둝 μΈμŠ€ν„΄μŠ€λ₯Ό λͺ‡ 가지 μΆ”κ°€ ν•­λͺ©μœΌλ‘œ λž˜ν•‘ν•˜μ§€λ§Œ 두 μΈμŠ€ν„΄μŠ€ 간에 λ™μΌν•œ push 및 replace λ©”μ„œλ“œμž…λ‹ˆλ‹€.

@timdorrλ‹˜, κ°μ‚¬ν•©λ‹ˆλ‹€.

router κ°€ 기본적으둜 νžˆμŠ€ν† λ¦¬ 싱글톀(싱글톀)을 λž˜ν•‘ν•˜λŠ” 경우 질문이 μ™œ withRouter() ꡬ성이 ν•„μš”ν•œκ°€κ°€ λ˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

ꡬ성 μš”μ†Œμ™€ 기둝 μΈμŠ€ν„΄μŠ€ κ°„μ˜ λŠμŠ¨ν•œ 결합을 ν—ˆμš©ν•©λ‹ˆκΉŒ(즉, ꡬ성 μš”μ†Œκ°€ 싱글톀 κ°œμ²΄μ— 직접 μ•‘μ„ΈμŠ€ν•˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•΄)? κ·Έλ ‡λ‹€λ©΄ μ•‘μ…˜ μƒμ„±μžμ—μ„œ νžˆμŠ€ν† λ¦¬ μΈμŠ€ν„΄μŠ€μ— μ•‘μ„ΈμŠ€ν•  λ•Œλ„ λ™μΌν•œ 논리가 μ μš©λ˜μ§€ μ•Šμ„κΉŒμš”?

λ„€, 그리고 λ§Œμ•½ 당신이 λ‹Ήμ‹ μ˜ 역사 μΈμŠ€ν„΄μŠ€λ₯Ό μ œκ³΅ν•˜κ³  λ‹Ήμ‹  μžμ‹ μ˜ 싱글톀 λͺ¨λ“ˆμ„ λ§Œλ“€κ³  싢지 μ•Šκ±°λ‚˜ λ§Œλ“€ 수 μ—†λ‹€λ©΄(JS λͺ¨λ“ˆ μ‹œμŠ€ν…œμ— μ΅μˆ™ν•˜μ§€ μ•Šλ‹€λ©΄ ν˜Όλž€μŠ€λŸ¬μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€). 직접 ν•˜κ³  μ‹Άλ‹€λ©΄ 저희 νŒ¨ν„΄μ„ λ”°λ₯΄μ…”도 μ’‹μŠ΅λ‹ˆλ‹€.

μ—¬λŸ¬ κ³ μ°¨ ꡬ성 μš”μ†Œμ— μ‚¬μš©ν•  수 μžˆλŠ” 방법에 λŒ€ν•΄ withRouter λ₯Ό λ¬Έμ„œν™”ν•˜λŠ” 것이 κ°€μΉ˜κ°€ μžˆλŠ”μ§€ 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ—¬μ „νžˆ 이것을 ν”Όν•˜λŠ” κ°€μž₯ 쒋은 방법을 μ•Œμ•„ λ‚΄λ €κ³  λ…Έλ ₯ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
connect(mapStateToProps, mapDispatchToProps)(withRouter(withAnalytics(withLanguage(TestForm)))); .

compose 와 같은 것을 μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆκΉŒ?

const enhance = compose(
  connect(mapStateToProps, mapDispatchToProps),
  withRouter,
  withAnalytics,
  withLanguage
);

export default enhance(TestForm);

κ·ΈλŸ¬λ‚˜ λ‚΄ μ‚¬μš© 사둀 μ»¨ν…μŠ€νŠΈμ—λŠ” λ‘œκ·ΈμΈν•œ μ‚¬μš©μž, ν˜„μž¬ μ–Έμ–΄, ν…Œλ§ˆ 정보 및 뢄석이 ν¬ν•¨λ˜μ–΄ μžˆμ–΄ λ§Žμ€ μ»¨ν…μŠ€νŠΈμ™€ μ—°κ²°λœ ꡬ성 μš”μ†Œκ°€ λ§Žμ•„ 이λ₯Ό μ–΄λ ΅κ²Œ λ§Œλ“­λ‹ˆλ‹€.

λ‹€λ₯Έ μ•„μ΄λ””μ–΄λŠ” withRouter 및 connect 논리λ₯Ό ν•˜λ‚˜μ˜ μ»¨ν…μŠ€νŠΈ λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ•„λž˜μ— λ³΅μ œν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. withAppContext() => props.app = { user, lang, theme, analytics, router, connect? } ?

이것은 λ¬Έμ„œλ‚˜ connect withRouter μ‚¬μš©μ˜ μ˜ˆμ— 도움이 λ κΉŒμš”?

@gaearon React Router 3.0.0κ³Ό μƒˆλ‘œμš΄ Egghead λ™μ˜μƒμ΄ λ‚˜μ˜¨ 지 μ–Όλ§ˆ λ˜μ§€ μ•Šμ•˜κ³  이 μŠ€λ ˆλ“œκ°€ μ—΄λ¦° 지 1년이 된 μ§€κΈˆ 이에 λŒ€ν•œ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

#1929μ—μ„œ μ™„λ£Œ

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰