ããã«ã¡ã¯ãã¿ããªã
ææ°ã®ã¢ããªã§react-routerãšreduxã䜿çšããŠããŸãããçŸåšã®URLãã©ã¡ãŒã¿ãŒãšã¯ãšãªã«åºã¥ããŠå¿ èŠãªç¶æ ã®å€æŽã«é¢é£ããããã€ãã®åé¡ã«çŽé¢ããŠããŸãã
åºæ¬çã«ãURLãå€æŽããããã³ã«ç¶æ ãæŽæ°ããå¿ èŠãããã³ã³ããŒãã³ãããããŸãã ç¶æ ã¯ããã³ã¬ãŒã¿ã䜿çšããŠãreduxã«ãã£ãŠå°éå ·ãä»ããŠæž¡ãããŸãã
@connect(state => ({
campaigngroups: state.jobresults.campaigngroups,
error: state.jobresults.error,
loading: state.jobresults.loading
}))
çŸæç¹ã§ã¯ã componentWillReceiveProps
ã©ã€ããµã€ã¯ã«ã¡ãœããã䜿çšããŠãreact-routerããã®URLå€æŽã«å¿çããŠããŸããããã¯ãURLãthis.props.params
ãšthis.props.query
å€æŽããããšãreact-routerãæ°ããå°éå
·ããã³ãã©ãŒã«æž¡ãããã§ãã
componentWillReceiveProps(nextProps) {
if (this.state.shouldupdate) {
let { slug } = nextProps.params;
let { citizenships, discipline, workright, location } = nextProps.query;
const params = { slug, discipline, workright, location };
let filters = this._getFilters(params);
// set the state accroding to the filters in the url
this._setState(params);
// trigger the action to refill the stores
this.actions.loadCampaignGroups(filters);
}
}
ã«ãŒãé·ç§»ã«åºã¥ããŠã¢ã¯ã·ã§ã³ãããªã¬ãŒããæšæºçãªã¢ãããŒãã¯ãããŸããããŸãã¯ã¹ãã¢ã®ç¶æ
ãå°éå
·ãä»ããŠæž¡ãã®ã§ã¯ãªããã³ã³ããŒãã³ãã®ç¶æ
ã«çŽæ¥æ¥ç¶ããããšã¯ã§ããŸããïŒ willTransitionTo
éçã¡ãœããã䜿çšããããšããŸããããthis.props.dispatchã«ã¢ã¯ã»ã¹ã§ããŸããã
@deowk this.props
ãšnextProps
ãæ¯èŒããŠãé¢é£ããããŒã¿ãå€æŽããããã©ããã確èªã§ããŸãã å€æŽãããŠããªãå Žåã¯ãã¢ã¯ã·ã§ã³ãå床ããªã¬ãŒããå¿
èŠã¯ãªããç¡éã«ãŒããåé¿ã§ããŸãã
@johanneslumpe ïŒç§ã®å Žåãcampaigngroupsã¯ããªã倧ããªãªããžã§ã¯ãã®ã³ã¬ã¯ã·ã§ã³ã§ããããã®ããã«æ¡ä»¶ãšããŠæ·±ããªããžã§ã¯ãæ¯èŒã䜿çšããã®ã¯éå¹ççã ãšæãããŸããïŒ
@deowkäžå€ã®ããŒã¿ã䜿çšããå Žåã¯ãåç §ãæ¯èŒããã ãã§ã
@deowkãã®åé¡ã«ã¯2ã€ã®éšåããããšæããŸãã 1ã€ç®ã¯ã componentWillReceiveProps()
ã¯ç¶æ
ã®å€åã«å¯Ÿå¿ããããã®çæ³çãªæ¹æ³ã§ã¯ãªããšããããšã§ããããã¯äž»ã«ãReduxã®ããã«åå¿çã«èããã®ã§ã¯ãªãã
ç§èš£ã¯ãã«ãŒã¿ãŒã®å Žæãå€æŽããããã³ã«èµ·åããã¢ã¯ã·ã§ã³ã¿ã€ããäœæããããšã§ãã ããã¯ãReactRouterã®æ¬¡ã®1.0ããŒãžã§ã³ã§ã¯ç°¡åã§ãã
// routeLocationDidUpdate() is an action creator
// Only call it from here, nowhere else
BrowserHistory.listen(location => dispatch(routeLocationDidUpdate(location)));
ããã§ãã¹ãã¢ã®ç¶æ
ã¯åžžã«ã«ãŒã¿ãŒã®ç¶æ
ãšåæããŸãã ããã«ãããäžèšã®ã³ã³ããŒãã³ãã®ã¯ãšãªãã©ã¡ãŒã¿ã®å€æŽãšsetState()
ã«æåã§å¯Ÿå¿ããå¿
èŠããªããªããŸããReduxã®ã³ãã¯ã¿ã䜿çšããã ãã§ãã
<Connector select={state => ({ filter: getFilters(store.router.params) })} />
åé¡ã®2çªç®ã®éšåã¯ããã¥ãŒã¬ã€ã€ãŒã®å€éšã§Reduxã®ç¶æ ã®å€åã«å¯Ÿå¿ããæ¹æ³ãããšãã°ã«ãŒãã®å€æŽã«å¿ããŠã¢ã¯ã·ã§ã³ãå®è¡ããæ¹æ³ãå¿ èŠãªããšã§ãã å¿ èŠã«å¿ããŠã説æãããããªåçŽãªã±ãŒã¹ã§åŒãç¶ãcomponentWillReceivePropsã䜿çšã§ããŸãã
ãã ãããã£ãšè€éãªå Žåã¯ãRxJSã䜿çšããããšããå§ãããŸãã ããã¯ãŸãã«ããªãã¶ãŒããã«ãèšèšãããŠããç®çã§ãâãªã¢ã¯ãã£ãããŒã¿ãããŒã
Reduxã§ãããè¡ãã«ã¯ãæåã«ã¹ãã¢ç¶æ
ã®èŠ³å¯å¯èœãªã·ãŒã±ã³ã¹ãäœæããŸãã ããã¯ãredux-rxã®observableFromStore()
ã䜿çšããŠè¡ãããšãã§ããŸãã
import { observableFromStore } from 'redux-rx';
const state$ = observableFromStore(store);
次ã«ãç£èŠå¯èœãªæŒç®åã䜿çšããŠç¹å®ã®ç¶æ å€åããµãã¹ã¯ã©ã€ãããã ãã§ãã ãã°ã€ã³ã«æåããåŸããã°ã€ã³ããŒãžãããªãã€ã¬ã¯ãããäŸã次ã«ç€ºããŸãã
const didLogin$ = state$
.distinctUntilChanged(state => !state.loggedIn && state.router.path === '/login')
.filter(state => state.loggedIn && state.router.path === '/login');
didLogin$.subscribe({
router.transitionTo('/success');
});
ãã®å®è£
ã¯ã componentDidReceiveProps()
ãããªåœä»€åãã¿ãŒã³ã䜿çšããåãæ©èœãããã¯ããã«åçŽã§ãã
ã圹ã«ç«ãŠã°å¹žãã§ãã
ããã¯æ°ããããã¥ã¡ã³ãã§å¿ èŠã§ãã ãšãŠãããæžãããŠããŸãã
@acdlite ïŒã©ããããããšãããããŸãããããªãã®ã¢ããã€ã¹ã¯æ¬åœã«ç§ã倧ãã«å©ããŠãããŸããããããç§ã¯æ¬¡ã®ããšã«èŠåŽããŠããŸã-> URLã®å€æŽã«å¿ããŠã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãããªã¬ãŒããããšã«ãã£ãŠã¹ãã¢ã®ç¶æ ãå€æŽããŸãã
ããã¯react-routerv0.13.3ã®å¯äžã®ãªãã·ã§ã³ã®ããã«æããããããwillTransitionToéçã¡ãœããã§ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãããªã¬ãŒããããšæããŸãã
class Results extends Component {
..........
}
Results.willTransitionTo = function (transition, params, query) {
// how do I get a reference to dispatch here?
};
@deowkç§ã®æšæž¬ã§ã¯ãreduxã€ã³ã¹ã¿ã³ã¹ã§çŽæ¥dispatch
ãåŒã³åºããŸãã
const redux = createRedux(stores);
BrowserHistory.listen(location => redux.dispatch(routeLocationDidUpdate(location)));
@deowkç§ã¯çŸåšã次ã®ããã«react router0.13.3ã§URLã®å€æŽããã£ã¹ãããããŸãã
Router.run(routes, Router.HistoryLocation, function(Handler, locationState) {
dispatch(routeLocationDidUpdate(locationState))
React.render(<Handler/>, appEl);
});
@acdliteã¯æ¬åœã«ãã説æãããŠããŸãïŒ ïŒ+1ïŒ
æ°ããããã¥ã¡ã³ãã«ãå«ããå¿
èŠãããããšã«åæããŸã:)
泚æãšããŠã BrowserHistory.history()
ã¯BrowserHistory.addChangeListener()
å€æŽãããŸããã
https://github.com/rackt/react-router/blob/master/modules/BrowserHistory.js#L57
ç·šéïŒ
ããã¯æ¬¡ã®ããã«ãªããŸãã
history.addChangeListener(() => store.dispatch(routeLocationDidUpdate(location)));
ãããŠããã®ã¬ãã¥ãŒãµãŒ@pburtchaellã®åæç¶æ ã¯ã©ãã§ããïŒ
ç§ã¯æ¬¡ã®èšå®ãããŠããŸãïŒ
// client.js
class App extends Component {
constructor(props) {
super(props);
this.history = new HashHistory();
}
render() {
return (
<Provider store={store}>
{renderRoutes.bind(null, this.history)}
</Provider>
);
}
}
// routes.js
export default function renderRoutes(history) {
// When the route changes, dispatch that information to the store.
history.addChangeListener(() => store.dispatch(routeLocationDidUpdate(location)));
return (
<Router history={history}>
<Route component={myAppView}>
<Route path="/" component={myHomeView} />
</Route>
</Router>
);
};
ããã«ãããã«ãŒããå€æŽããããã³ãšã¢ããªãæåã«èªã¿èŸŒãŸãããã³ã«ã routeLocationDidUpdate()
ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãèµ·åããŸãã
@pburtchaell routeLocationDidUpdate
ãå
±æã§ããŸããïŒ
@gyzerokãã¡ããã§ãã ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒã§ãã
// actions/location.js
export function routeLocationDidUpdate(location) {
return {
type: 'LOCATION_UPDATE',
payload: {
...location,
},
};
}
@pburtchaellã ãããããªãã®äŸã§ã¯ãç¹å®ã®ã«ãŒãã«å¿ èŠãªããŒã¿ãã©ãã§ãã§ããããã®ããç§ã¯éãã«ç解ããŠããŸãã
äžèšã®ç§ã®äŸã®ããå®å šãªããŒãžã§ã³ã¯æ¬¡ã®ãšããã§ãã
https://github.com/acdlite/redux-react-router/blob/master/README.md#bonus -reacting-to-state-changes-with-redux-rx
@pburtchaellã¯ããã®ã³ãŒãã®éåæããŒãžã§ã³ã䜿çšããŠïŒRESTåŒã³åºããªã©ããïŒããŒã¿ãååŸãããšæããŸãã ç§ã確信ããŠããªãã®ã¯ãããã§ã¯äœã§ããïŒ ç§ã¯ãããåºã«è¡ããšæããŸããããããã®åºã¯ç§ãããããããlocationStoreã§ããã§ãããã
<strong i="7">@connect</strong>
ã«ãèšããŸããã
<Comments />
ãã§ã«commentStoreã«ãæ¥ç¶ãïŒãµãã¹ã¯ã©ã€ãïŒãããŠããã®ã¯ã©ãã§ããïŒ ãŸãã¯ãcommentsStoreã«ãããã®ãã±ãŒã·ã§ã³ã¢ã¯ã·ã§ã³ãè¿œå ç»é²ããŸããïŒ
ã®ãããªURL
/comments/123
åžžã«ã³ã¡ã³ãã³ã³ããŒãã³ãã«ãçµåããããã®ã§ãã©ãããã°åå©çšã§ããŸããïŒ ãããã°ãããŠãããªãç³ãèš³ãããŸãããããã§éåžžã«æ··ä¹±ããŠããŸãã ç§ãèŠã€ãã確ããªäŸããããŸããã
ç§ãããã«åãçµãã§ãããéçãªfetchData(dispatch, params)
ã¡ãœãããåŒã³åºãæ¹æ³ãèããŠããŸãïŒãµãŒããŒãæåã®ã¬ã³ããªã³ã°ã®åã«éåæFETCHã¢ã¯ã·ã§ã³ããã£ã¹ãããããããã«åŒã³åºããããéçã§ãïŒã
dispatch
ãžã®åç
§ã¯ã³ã³ããã¹ãå
ã«ååšããããã fetchData
ã¯ã©ã€ã¢ã³ãåŽåŒã³åºãã§ãããååŸããæãã¯ãªãŒã³ãªæ¹æ³ã¯ãåŒã³åºããè¡ãConnector
ãããªã³ã³ããŒãã³ãã ãšæããŸãã fetchData
ãŸãã¯shouldFetchData
ããŸãã¯æã£ãŠããselect
ãžã®ã³ãŒã«ããã¯GETåç
§dispatch
ãšäžç·ã«state
ãæã
ã¯æ€æ»ããããšãã§ããŸãã®ã§ãçŸåšã®store
ç¶æ
ã§ãå¿
èŠã«å¿ããŠFETCH
ã¢ã¯ã·ã§ã³ããã£ã¹ãããããŸãã
åŸè
ã¯ããç°¡æœã§ããã select
ãçŽç²é¢æ°ã®ãŸãŸã§ãªããã°ãªããªããšããäºå®ãç ŽããŸãã åè
ã調ã¹ãŸãã
ç§ã®è§£æ±ºçã¯ããã§ãããç§ã®èšå®ïŒéåæ_FETCH
ã¢ã¯ã·ã§ã³ããã£ã¹ãããããéçfetchData(dispatch, state)
ã¡ãœããïŒã«åãããŠèª¿æŽãããŠããŸãããé©åãªããããã£ã䜿çšããŠæž¡ãããã³ãŒã«ããã¯ãåŒã³åºããŸãïŒ httpsïŒ// gist.github.com/grrowl/6cca2162e468891d8128 âãã ããwillTransitionToã¯äœ¿çšããªããããããŒãžã®é·ç§»ãé
ãããããšã¯ã§ããŸããã
ééããªãããã¥ã¡ã³ãã«è¿œå ããå¿ èŠããããŸãïŒ ãreact-routerã§ã®äœ¿çšãã»ã¯ã·ã§ã³ã§å¯èœã§ãã
1.0ã®ãªãªãŒã¹åŸããããè¡ãå ¬åŒã®æ¹æ³ããããŸãã
@gaearonãèããŠããããã§ãã
次ã«ãç£èŠå¯èœãªæŒç®åã䜿çšããŠç¹å®ã®ç¶æ å€åããµãã¹ã¯ã©ã€ãããã ãã§ãã
ã¹ãã¢ãã«ãŒãã®å€æŽãšåæãããããã«ç£èŠå¯èœãªã¹ããªãŒã ãèšå®ããŸããããŸããã¹ãã¢ãç£èŠããããã®ã¹ããªãŒã ãèšå®ããŸããã ã¹ãã¢ã§å€ãå€æŽããããšããç¹ã«ã¢ããªã®ä»ã®å Žæã§ãã©ãŒã ãæ£åžžã«éä¿¡ããçµæãšããŠå€ãundefined
ããæå¹ãªæååã«å€æŽããããšãã«ãæ°ããã«ãŒãã«ç§»è¡ããããšã«èå³ããããŸãã
2ã€ã®ã¹ããªãŒã ãã»ããã¢ãããããŠæ©èœããã¹ãã¢ãæŽæ°ãããŠããŸãããRxã¯åããŠã§ãç£èŠå¯èœãªã¯ãšãªã«åé¡ããããŸã...ãã€ã³ã¿ã¯ãããŸããïŒ ç§ã¯æ£ããæ¹åã«é²ãã§ããŸããïŒ distinctUntilChanged
ãšé¢ä¿ãããããšã¯ç¢ºãã§ãããçŸæç¹ã§ã¯ç§ã®éººãçŒããŠããŸããå©ããŠããã ããã°å¹žãã§ã:)
ç·šéïŒç¢ºèªïŒ ãã¿ãŸãããç§èªèº«ã®è³ªåã«çããŸããã 以äžã®æ¬äŒŒã³ãŒãã æãããããã«èŠãããã©ããæããŠãã ããã
const didChangeProject$ = state$
.distinctUntilChanged(state => state.project._id)
.filter(state => typeof state.project._id !== 'undefined');
ïŒ177ãæ¯æããŠéäŒã ã«ãŒãã£ã³ã°ã®ææžåã«åãæãããšãã¯ããã¹ãŠã®ã·ããªãªãã«ããŒããå¿ èŠããããŸããç¶æ å€æŽæã®ãªãã€ã¬ã¯ããèŠæ±ã³ãŒã«ããã¯æã®ãªãã€ã¬ã¯ããªã©ã§ãã
ç§ã¯ãããéããŠããããšãç¥ã£ãŠããŸã..ããããçŸåšããŒã¿çã®React 0.14ãšããŸããŸãª1.0ã®äŸåé¢ä¿ã§ãããã«å¯ŸããæŽæ°ããããŸããïŒããã§ãªãå Žåã¯ãReact 0.14ãreact-routerãreduxãªã©ã®æ°ããæ©èœã«é¢ãããã¥ãŒããªã¢ã«ãè¡ãããšãã§ããŸãæžãããŠããŸããïŒ ããããã¹ãŠãåæã«åŠã³/ç解ããªãããä»åŸã®å€æŽã«ã€ããŠææ°ã®ç¶æ ã«ä¿ãšããšããŠããç§ãã¡ã®å€ããããããã§ãã ç©äºãæµåçãªç¶æ ã«ããããšã¯ç¥ã£ãŠããŸããïŒããã..ãããš..æå³ãããŠããŸããïŒãããŸããŸãªäŸã®ããŒã¹ãäºãã«ããŸãæ©èœããªãã®ãèŠãŠããŠãæ°æ¥çµã£ãŠãæŽæ°ãããã¢ããªãåäœãããããšãã§ããŸããã«ãŒãã£ã³ã°ä»ãã ç§ã¯ãŸã ããããã¹ãŠãã©ã®ããã«æ©èœããããç解ããã®ã«å°ãèŠåŽããŠããã®ã§ãããããç§èªèº«ã®ããã§ããææ°ã®ãã®ã§æŽæ°ããããã¥ãŒããªã¢ã«ãããã«åºããšæã£ãŠããŸãã
ãã¥ãŒããªã¢ã«ãã§ãããŸã§ãã«ãŒãã£ã³ã°ã®ããexamples/real-world
ãèªç±ã«èŠãŠãã ããã çŸåšã¯ãææ°ãã€æé«ãã§ã¯ãããŸããããæ£åžžã«æ©èœããŸãã
æãåèã«ãªãã³ã¡ã³ã
@deowkãã®åé¡ã«ã¯2ã€ã®éšåããããšæããŸãã 1ã€ç®ã¯ã
componentWillReceiveProps()
ã¯ç¶æ ã®å€åã«å¯Ÿå¿ããããã®çæ³çãªæ¹æ³ã§ã¯ãªããšããããšã§ããããã¯äž»ã«ãReduxã®ããã«åå¿çã«èããã®ã§ã¯ãªããç§èš£ã¯ãã«ãŒã¿ãŒã®å Žæãå€æŽããããã³ã«èµ·åããã¢ã¯ã·ã§ã³ã¿ã€ããäœæããããšã§ãã ããã¯ãReactRouterã®æ¬¡ã®1.0ããŒãžã§ã³ã§ã¯ç°¡åã§ãã
ããã§ãã¹ãã¢ã®ç¶æ ã¯åžžã«ã«ãŒã¿ãŒã®ç¶æ ãšåæããŸãã ããã«ãããäžèšã®ã³ã³ããŒãã³ãã®ã¯ãšãªãã©ã¡ãŒã¿ã®å€æŽãš
setState()
ã«æåã§å¯Ÿå¿ããå¿ èŠããªããªããŸããReduxã®ã³ãã¯ã¿ã䜿çšããã ãã§ããåé¡ã®2çªç®ã®éšåã¯ããã¥ãŒã¬ã€ã€ãŒã®å€éšã§Reduxã®ç¶æ ã®å€åã«å¯Ÿå¿ããæ¹æ³ãããšãã°ã«ãŒãã®å€æŽã«å¿ããŠã¢ã¯ã·ã§ã³ãå®è¡ããæ¹æ³ãå¿ èŠãªããšã§ãã å¿ èŠã«å¿ããŠã説æãããããªåçŽãªã±ãŒã¹ã§åŒãç¶ãcomponentWillReceivePropsã䜿çšã§ããŸãã
ãã ãããã£ãšè€éãªå Žåã¯ãRxJSã䜿çšããããšããå§ãããŸãã ããã¯ãŸãã«ããªãã¶ãŒããã«ãèšèšãããŠããç®çã§ãâãªã¢ã¯ãã£ãããŒã¿ãããŒã
Reduxã§ãããè¡ãã«ã¯ãæåã«ã¹ãã¢ç¶æ ã®èŠ³å¯å¯èœãªã·ãŒã±ã³ã¹ãäœæããŸãã ããã¯ãredux-rxã®
observableFromStore()
ã䜿çšããŠè¡ãããšãã§ããŸãã次ã«ãç£èŠå¯èœãªæŒç®åã䜿çšããŠç¹å®ã®ç¶æ å€åããµãã¹ã¯ã©ã€ãããã ãã§ãã ãã°ã€ã³ã«æåããåŸããã°ã€ã³ããŒãžãããªãã€ã¬ã¯ãããäŸã次ã«ç€ºããŸãã
ãã®å®è£ ã¯ã
componentDidReceiveProps()
ãããªåœä»€åãã¿ãŒã³ã䜿çšããåãæ©èœãããã¯ããã«åçŽã§ããã圹ã«ç«ãŠã°å¹žãã§ãã