ãŸã第äžã«ãç§ã¯ãã®ã©ã€ãã©ãªãšçããã䜿çšããŠãããã¿ãŒã³ã倧奜ãã§ãã ðð
reduxã䜿çšããŠå圢ã¢ããªãæ§ç¯ããããšããŠããŸãã æåã®ããŒãžã®èªã¿èŸŒã¿ãè¿ãåã«ãã¹ãã¢ãïŒãµãŒããŒã«ïŒèªã¿èŸŒãŸãããŸã§åŸ
ã€æ¹æ³ãç解ããå¿
èŠãããããšãé€ããŠããããŸã§ã®ãšããããŸãæ©èœããŠããŸãã çæ³çã«ã¯ãããŒãã¯ã¹ãã¢èªäœã§è¡ãããã¹ãã§ããã dispatch(userActions.load())
ãåŒã³åºããšãã¹ãã¢ã¯æ°ããç¶æ
ïŒã€ãŸãã return { ...state, loading: true };
ïŒãè¿ããªããã°ãªããªãããããåŸ
ã€ã dispatch()
ã¯ãäœããã®çç±ã§æž¡ãããã¢ã¯ã·ã§ã³ãè¿ããŸãã ç§ã¯æ¬åœã«äœãã®ãããªãã®ã欲ããã§ã...
dispatch(someAsyncAction, successAction, failureAction) => Promise
...ä»ã®2ã€ã®ã¢ã¯ã·ã§ã³ã®ããããããã£ã¹ãããããããŸã§promiseã解決ãããªãå Žåã
ããã¯ããã«ãŠã§ã¢ãã¿ãŒã³ã§æå¹ã«ã§ãããããªãã®ã§ããïŒ
ç§ã¯å®å šã«ããŒã¹ããå€ããŠããŸããïŒãããè¡ãç°¡åãªæ¹æ³ã¯ãã§ã«ãããŸããïŒ
ããããšãã
ãããããããšãïŒ
çæ³çã«ã¯ãããŒãã¯åºèèªäœã§è¡ãããå¿ èŠããããŸã
Reduxã¯ãã¹ãã¢ãå®å šã«åæããŠããããšã匷å¶ããŸãã ããªãã説æããããšã¯ã代ããã«ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒã§è¡ãããã¹ãã§ãã
ããã©ã«ãã®ãµã³ã¯ããã«ãŠã§ã¢ã§ãå¯èœãããããªããšç§ã¯æããŸãã ã¢ã¯ã·ã§ã³ã®äœæè ã¯æ¬¡ã®ããã«ãªããŸãã
export function doSomethingAsync() {
return (dispatch) => {
dispatch({ type: SOMETHING_STARTED });
return requestSomething().then(
(result) => dispatch({ type: SOMETHING_COMPLETED, result }),
(error) => dispatch({ type: SOMETHING_FAILED, error })
);
};
}
ã¹ãã¢ã§ã®å®éã®ïŒãã现ããïŒã¢ã¯ã·ã§ã³ã®åŠçã
ãã€ã©ãŒãã¬ãŒããåé€ããã«ã¹ã¿ã ããã«ãŠã§ã¢ãäœæããããšãã§ããŸãã
倩æïŒ æãããªäœããèŠèœãšããŠãããšæããŸããã ç§ã¯_doing_ãš_storing_ã®åé¢ã奜ãã§ãã
ãã®ã©ã€ãã©ãªãæé·ããã®ã楜ãã¿ã«ããŠããŸããããã§ã«ããªãå®æããŠããŸãã 也æ¯ã@ gaearonïŒ
ãã®ãããªã«ã¹ã¿ã ããã«ãŠã§ã¢ãäœæããããšãã§ããŸã
export default function promiseMiddleware() {
return (next) => (action) => {
const { promise, ...rest } = action;
if (!promise) {
return next(action);
}
next({ ...rest, readyState: 'request' );
return promise.then(
(result) => next({ ...rest, result, readyState: 'success' }),
(error) => next({ ...rest, error, readyState: 'failure' })
);
};
}
ããã©ã«ãã®ä»£ããã«äœ¿çšããŸãã
ããã«ããã次ã®ãããªéåæã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãäœæã§ããŸãã
function doSomethingAsync(userId) {
return {
type: SOMETHING,
promise: requestSomething(userId),
userId
};
}
ãããŠããããã«å€ãããã
{ type: SOMETHING, userId: 2, readyState: 'request' }
{ type: SOMETHING, userId: 2, readyState: 'success' }
{ type: SOMETHING, userId: 2, readyState: 'failure' }
ããããããããã§ãããããŠç§ãæåã®è³ªåããããšãã«ç§ãå¿ã«çããŠãããã®ã®å€ãã ã¹ãã¢å
ã®readyState
ããã§ãã¯ããããã«if
ãè¿œå ãã代ããã«ãã¢ã¯ã·ã§ã³å®æ°ã®æ°ãæžãããšãããã¬ãŒããªãã奜ããã©ããã¯ããããŸããã ç§ã¯addtionalã®æã€å¥œããããããªããšæã_SUCCESS
ãš_FAILURE
ã ãå
¥ããŠåé¿ããããã«ãåã¢ã¯ã·ã§ã³ã®ããŒãžã§ã³ãif
å
åŽcase
ã
ã§ããããããšãã
ãããããã¯å®å
šã«ããªãã®å¥œã¿æ¬¡ç¬¬ã§ãã types: { request: ..., success: ..., failure: ... }
ãã¢ã¯ã·ã§ã³ã«å€ããåæ§ã®ããŒãžã§ã³ãäœæã§ããŸãã ããããã©ã€ãã©ãªã«çŒãä»ããã®ã§ã¯ãªããããã«ãŠã§ã¢ã«ããããšã®ãã€ã³ãã§ãã誰ãããããã®ããšã«ç¬èªã®å¥œã¿ãæã£ãŠããŸãã
// Middleware
export default function promiseMiddleware() {
return (next) => (action) => {
const { promise, types, ...rest } = action;
if (!promise) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = types;
next({ ...rest, type: REQUEST });
return promise.then(
(result) => next({ ...rest, result, type: SUCCESS }),
(error) => next({ ...rest, error, type: FAILURE })
);
};
}
// Usage
function doSomethingAsync(userId) {
return {
types: [SOMETHING_REQUEST, SOMETHING_SUCCESS, SOMETHING_FAILURE],
promise: requestSomething(userId),
userId
};
}
ãããç§ã¯ãã®è§£æ±ºçã倧奜ãã§ãã æåã«ææ¡ãããœãªã¥ãŒã·ã§ã³ã®ããã«ã then()
ãšdispatch()
ãžã®è¿œå ã®åŒã³åºããè¡ããããã¯ããã«åªããŠããŸãã ããã«ãŠã§ã¢ã«ãæåŸ
ãã ããã
ã©ã®ããã«ïŒãããŠ;-)ãããæ©èœããããæããŠãã ããïŒ
ã«ã¹ã¿ã ããã«ãŠã§ã¢ã¯ããŸããã¹ãããŠããŸããã
}
ïŒ-1ãã€ã³ãðïŒãçç¥ããŸããããããã¯é
åã®ããã«æ©èœããŸããïŒ åããŠã
ïŒ+1ïŒ
@erikrasãµãŒããŒã§çŽæã解決ãããã®ãåŸ ã£ãŠãã©ã®ããã«å®è£ ããã®ããç§ã¯
ããã¯åãªãæ¬äŒŒã³ãŒããªã®ã§ãã©ãã«ã貌ãä»ããªãã§ãã ããããã ããreact-routerïŒAPIã¯reduxãšåããããéãå€åããŸãïŒã䜿çšããŠããŸãã
app.get('/my-app', (req, res) => {
Router.run(routes, req.path, (error, initialState) => {
Promise.all(initialState.components
.filter(component => component.fetchData) // only components with a static fetchData()
.map(component => {
// have each component dispatch load actions that return promises
return component.fetchData(redux.dispatch);
})) // Promise.all combines all the promises into one
.then(() => {
// now fetchData() has been run on every component in my route, and the
// promises resolved, so we know the redux state is populated
res.send(generatePage(redux));
});
});
});
ããã¯äœããã¯ãªã¢ããŸããïŒ
@iest
Slackã§ã®åé¡ã®åŒçšïŒ
ç§ã¯ã«ãŒããã³ãã©ãŒãæã£ãŠããŸã
static async routerWillRun({dispatch}) { return await dispatch(UserActions.fooBar()); }
ããã§ã
UserActions.fooBar()
ã¯æ¬¡ã®ãšããã§ããexport function fooBar() { return dispatch => { doAsync().then(() => dispatch({type: FOO_BAR})); }; }
次ã«ããµãŒããŒã¬ã³ããªã³ã°ã§æ¬¡ã®ããã«ãªããŸãã
yield myHandler.routerWillRun({dispatch: redux.dispatch});
ããããããã¯æ©èœããŸããã
ããã§ã®åé¡ã¯ã fooBar
ã®ãã¹ããããã¡ãœããããå®éã«ã¯äœãè¿ããªãããšã ãšæããŸãã
äžæ¬åŒ§ãåé€ããŸãã
export function fooBar() {
return dispatch =>
doAsync().then(() => dispatch({type: FOO_BAR}));
}
ãŸãã¯ãæ瀺çãªreturn
ã¹ããŒãã¡ã³ããè¿œå ããŸãã
export function fooBar() {
return dispatch => {
return doAsync().then(() => dispatch({type: FOO_BAR}));
};
}
ãããã«ãããäžèšã®ããã«ã«ã¹ã¿ã promiseããã«ãŠã§ã¢ã䜿çšããæ¹ãç°¡åãããããŸããã
@erikras ïŒRouter.runã®ã³ãŒã«ããã¯ã§ïŒ initialState.components
ãšããŠæã£ãŠãããã®ã«å¯ŸããŠfetchDataã¡ãœãããåŒã³åºããŠããæåŸã®ã³ã¡ã³ãã«é¢ããŠãã³ã³ããŒãã³ãåç
§ãååŸãããªããžã§ã¯ãã¯ãäžèŽããã«ãŒããã³ãã©ãŒã®ã¿ãè¿ããŸãã äžèŽããã«ãŒããã³ãã©ãŒã§ã¯ãªãå¯èœæ§ãããã³ã³ããŒãã³ããã€ãŸãåã³ã³ããŒãã³ãã«å°éããããšã«ã€ããŠã©ãæããŸããïŒãã ããããŒã¿ããã§ããããå¿
èŠããããŸããïŒ
ãããç§ã話ããŠããããšã®äŸã§ã
import React from 'react';
import Router from 'react-router';
import {Route, RouteHandler, DefaultRoute} from 'react-router';
//imagine Bar needs some data
const Bar = React.createClass({
render(){
return(
<div>bar</div>);
}
});
const Foo = React.createClass({
render(){
return (
<div>
foo
<Bar/>
</div>);
}
});
const App = React.createClass({
render(){
return (
<div>
<RouteHandler />
</div>
);
}
});
const routes = (
<Route path="/" handler={App} name="App">
<DefaultRoute handler={Foo} name="Foo"/>
</Route>
);
Router.run(routes,'/',function(Root,state){
console.log(state);
});
åºåïŒ
{ path: '/',
action: null,
pathname: '/',
routes:
[ { name: 'App',
path: '/',
paramNames: [],
ignoreScrollBehavior: false,
isDefault: false,
isNotFound: false,
onEnter: undefined,
onLeave: undefined,
handler: [Object],
defaultRoute: [Object],
childRoutes: [Object] },
{ name: 'Foo',
path: '/',
paramNames: [],
ignoreScrollBehavior: false,
isDefault: true,
isNotFound: false,
onEnter: undefined,
onLeave: undefined,
handler: [Object] } ],
params: {},
query: {} }
ã«ãŒãå ã®ããŒã«ã¢ã¯ã»ã¹ã§ããªããªããŸã
@erikrasçŽ æŽãããïŒ ããããŸãã«ç§ãè¡ãããã«ãŒãã§ãã å ±æããŠããã ãããããšãããããŸãã
@iestäžèŽããã«ãŒããç¹°ãè¿ãããšã§ããã«ãŒããäžãããšããããããæå³çã«
@mattybowããã¯æ¬åœã§ãã äœããããŒãããããã«ã«ãŒãã«ãªãã³ã³ããŒãã³ãã_æ¬åœã«_å¿
èŠãªå Žåãå¯äžã®ãªãã·ã§ã³ã¯React.renderToString()
1åå®è¡ãïŒçµæãç Žæ£ïŒããã¹ãŠã®ããŒããcomponentWillMount()
ã§å®è¡ããããšã§ããããªããè¡ãããã«çŽæãä¿åããŸãã ããã¯ã react-router
ããµãŒããŒåŽã®ã¬ã³ããªã³ã°ããµããŒãããåã«ãç§ãç¬èªã«éçºããã«ãŒãã£ã³ã°ãœãªã¥ãŒã·ã§ã³ã§è¡ã£ãŠããããšã§ãã ããŒããè¡ãããã«éã«ãŒãã³ã³ããŒãã³ããå¿
èŠã«ãªãããšã¯ãèšèšäžã®åé¡ã®å
åã§ããå¯èœæ§ãããããšããå§ãããŸãã ã»ãšãã©ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãã«ãŒãã¯ãã®ã³ã³ããŒãã³ããå¿
èŠãšããããŒã¿ãç¥ã£ãŠããŸãã
@erikras
ããã§ã®ãœãªã¥ãŒã·ã§ã³ã®å
šäœçãªäŸã確èªããããã®å
¬éãªããžããªã¯ãããŸããïŒ
@transedwardããããã£ãã®ã§ãããããã§è©³ãã説æããæ¹æ³ã䜿çšãããããŸã§ã®
é«åºŠãªååã®äŸã§+1
ç§ã¯ãããã©ãã«è¡ãã®ãã倧奜ãã§ãïŒ
@transedwardããã¯ãç§ããŸãšããæå 端ã®æè¡ããã¹ãŠåãããµã³ãã«ãããžã§ã¯ãã§ãã https://github.com/erikras/react-redux-universal-hot-example/
@erikrasããã¯ãããïŒ PRãéä¿¡ããŠããã®READMEããã³React Hot Loaderã®ããã¥ã¡ã³ãã®ãã¹ã¿ãŒã¿ãŒããããã»ã¯ã·ã§ã³ã«è¿œå ããŠããã ããŸããïŒ
ããããšãïŒ æåºãããPRã
@erikrasçŽ æŽããã-ããããšãïŒ
ãã®äŒè©±ã®ããã€ãã®ã¢ã€ãã¢ã«åºã¥ããŠãçŽæãåŠçããããã«ãŠã§ã¢ãäœæããããšã«æ³šæããŠãã ããïŒ //github.com/pburtchaell/redux-promise-middlewareã
@pburtchaellåæ§@acdliteããããšã«ããããã®ã©ã€ãã©ãªããããŸãã https://github.com/acdlite/redux-promise
ããã«é¢ãã2ã€ã®èãïŒ
次ã«ãããŒãžãã¬ã³ããªã³ã°ããæºåãã§ããŠãããã©ããã確èªããã«ã¯ããã¹ãŠã®ãããã¹ãå®äºãããã©ããã確èªããã ãã§ãã ãããããééãããã¹ãŠã®ãããã¹ããã§ãŒã³ããä¿çäžã®ãããã¹ããªãå Žåã«ãããã¹ãæäŸããããã«ãŠã§ã¢ã䜿çšããŸãã
ã¡ãã»ãŒãž3ãã¬ã³ããªã³ã°ãããšãã¡ãã»ãŒãžã³ã³ããã¯<Message id={3}>
ãã¬ã³ããªã³ã°ããã¡ãã»ãŒãžã»ã¬ã¯ã¿ã¯state.msgs[3]
ãååšãããã©ããã確èªããååšããªãå Žåã¯ã¡ãã»ãŒãžèªã¿èŸŒã¿promiseããã£ã¹ãããããŸãã
ãããã£ãŠã2ã€ãçµã¿åããããšãã³ã³ããŒãã³ããå¿ èŠãªããŒã¿ãèªåéžæãããããããã€å®äºããããããããŸãã
ãã·ãªã¢ã«åã§ããªããã®ãã¹ãã¢ãã¢ã¯ã·ã§ã³ã«å ¥ããªãã§ãã ããããšç¢ºä¿¡ããŠããŸãã ããã¯ç§ã«ãšã£ãŠæ¬åœã«ããŸãæ©èœããŠããïŒãããŠäŸãã°ã¿ã€ã ãã©ãã«ãèš±å¯ãããŠããïŒäžå€æ¡ä»¶ã®1ã€ã§ããããããå€æŽããããšãæ€èšããããã®_éåžžã«_説åŸåã®ããçç±ãå¿ èŠã§ãã
次ã«ãããŒãžãã¬ã³ããªã³ã°ããæºåãã§ããŠãããã©ããã確èªããã«ã¯ããã¹ãŠã®ãããã¹ãå®äºãããã©ããã確èªããã ãã§ãã ãããããééãããã¹ãŠã®ãããã¹ããã§ãŒã³ããä¿çäžã®ãããã¹ããªãå Žåã«ãããã¹ãæäŸããããã«ãŠã§ã¢ã䜿çšããŸãã
ããã¯å®éã«ã¯æçµçã«åºã«çŽæãããå¿ èŠã¯ãããŸããããããŠç§ã¯ããã奜ãã§ãã éãã¯ããã£ã¹ããããã§ãŒã³ã®æåŸã§ã¯ãçã®ã¢ã¯ã·ã§ã³ã«ãããã¹ãå«ãŸããŠããªãããšã§ãã ãããã¯ã代ããã«åè¿°ã®ããã«ãŠã§ã¢ã«ãã£ãŠãåéããããŸãã
ãããã¹ãæ±ããšãã«ç§ãããè¡ãããšã®1ã€ã¯ããããã¹ãžã®åââç §ãç¶æããããšã§ããããã«ãããåãããšã«å¯Ÿããä»ã®èŠæ±ãçºçãããšãã«ãåããããã¹ãè¿ãã ãã§ããããŠã³ã¹ãæäŸãããŸãã 次ã«ãpromiseãå®äºããåŸãã°ããããŠåç §ãåé€ããæ§æå¯èœãªãã£ãã·ã¥ãæäŸããŸãã
Reduxã§ãããã®åç §ãã©ããããçåã«æãã®ã§ãå®éã®ã¢ããªã§Reduxã䜿ãå§ããå¿ èŠããããŸãã actionCreatorãã¹ããŒãã¬ã¹ã«ããïŒãŸãã¯å°ãªããšãç¶æ ãæ瀺çã«ããïŒããã«ãããããã¹ãã¢ã«åºå®ããããšæããŸãã ã¢ã¯ã·ã§ã³ãä»ããŠpromiseãæž¡ãããšã¯ãããããšã¯ã¹ããŒãããããã®åªããæ¹æ³ã§ããããã®åŸãäœããã®æ¹æ³ã§ãããåãæ»ãå¿ èŠããããŸãã ããŒãã
@wmertensã®æåŸã®ãã€ã³ããžã®çããæ¬åœã«æ¥œãã¿ã«ããŠããŸãã
è€æ°ã®åæåŒã³åºããåé¿ããïŒäœããä¿çäžã®å Žåã¯äœãããªãïŒããšã¯é »ç¹ãªãŠãŒã¹ã±ãŒã¹ã§ãããããã«çããæåã®æ¹æ³ãããããŸããïŒactionCreatorããã¹ãã¢ã®ç¶æ
ã«ã¢ã¯ã»ã¹ã§ããªãããïŒã
actionCreatorãŠãŒã¶ãŒïŒã³ã³ããŒãã³ãïŒã¯ãã¢ã¯ã·ã§ã³ããã£ã¹ãããã§ãããã©ãããç¶æ ã§æ¯å確èªããå¿ èŠããããŸããïŒ æ¯åãããããªããã°ãªããŸãã..å€åããªãã¯ãããå ãããªãèªèº«ã®@connectã¢ãããŒã·ã§ã³ãå°å ¥ããå¿ èŠããããŸããïŒ
actionCreatorããã¹ãã¢ã®ç¶æ ã«ã¢ã¯ã»ã¹ã§ããªããã
ã©ãããŠïŒ ãµã³ã¯ããã«ãŠã§ã¢ã䜿çšããã°ãåé¡ãªãå®è¡ã§ããŸãã
function doSomething() {
return { type: 'SOMETHING' };
}
function maybeDoSomething() {
return function (dispatch, getState) {
if (getState().isFetching) {
return;
}
dispatch(doSomething());
};
}
store.dispatch(maybeDoSomething());
ããã¯ããã解決ããŸãïŒ
ãã°ããã®éïŒçç±ããªãïŒactionCreatorã§ç¶æ
ã«ã¢ã¯ã»ã¹ããã®ã¯æªãç¿æ
£ã ãšæã£ãŠããŸãã^^ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒã®åŒã³åºãå
ã¯ç¶æ
ã«ã¢ã¯ã»ã¹ã§ããã®ã§ãactionCreatorãã¢ã¯ã»ã¹ã§ããªãçç±ãããããŸããã :)
ããããšã@gaearon
@gaearonã¯ããµã³ã¯ãšåå¥ã®ã¢ã¯ã·ã§ã³ã䜿çšãããã®ææ³ã§ãhttp://gaearon.github.io/redux/docs/api/applyMiddleware.htmläžèšã®åçãããæãŸããã§ãïŒ
ãã®ãããªã«ã¹ã¿ã ããã«ãŠã§ã¢ãäœæããããšãã§ããŸã
export default function promiseMiddleware() {
return (next) => (action) => {
const { promise, ...rest } = action;
if (!promise) {
return next(action);
}
next({ ...rest, readyState: 'request' );
return promise.then(
(result) => next({ ...rest, result, readyState: 'success' }),
(error) => next({ ...rest, error, readyState: 'failure' })
);
};
}
ããã©ã«ãã®ä»£ããã«äœ¿çšããŸãã
ããã«ããã次ã®ãããªéåæã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒãäœæã§ããŸãã
function doSomethingAsync(userId) {
return {
type: SOMETHING,
promise: requestSomething(userId),
userId
};
}
ãããŠããããã«å€ãããã
{ type: SOMETHING, userId: 2, readyState: 'request' }
{ type: SOMETHING, userId: 2, readyState: 'success' }
{ type: SOMETHING, userId: 2, readyState: 'failure' }
ãŸãã
ç§ã¯æåŸã®éšåã«ã€ããŠãããªããæå³ãããšæããŸãïŒ
{ type: SOMETHING, userId: 2, readyState: 'request' }
{ type: SOMETHING, userId: 2, result, readyState: 'success' }
{ type: SOMETHING, userId: 2, error, readyState: 'failure' }
èªåçæããããã®ã䜿çšããã®ã§ã¯ãªããpromiseã®success
ãŸãã¯failure
ã³ãŒã«ããã¯ã«å¯ŸããŠåå¥ã®ã¢ã¯ã·ã§ã³ãäœæãããã©ããã«äŸåããŠãããšæããŸãã
ããªãã®ãµã³ã¯ã®äŸã§ã¯ïŒ
function makeASandwichWithSecretSauce(forPerson) {
// Invert control!
// Return a function that accepts `dispatch` so we can dispatch later.
// Thunk middleware knows how to turn thunk async actions into actions.
return function (dispatch) {
return fetchSecretSauce().then(
sauce => dispatch(makeASandwich(forPerson, sauce)),
error => dispatch(apologize('The Sandwich Shop', forPerson, error))
);
};
}
ãã®å ŽåããœãŒã¹ã®ãã§ããã«ã¯ããŸããŸãªç¶æ³ãçºçããå¯èœæ§ããããããã·ãŒã¯ã¬ãããœãŒã¹ã®ãã§ããã«å€±æããå Žåã«äžè¬çãªãšã©ãŒã³ãŒã«ããã¯ãèšå®ããããšã¯å¿ ãããæå³ããããŸããã
ãããã£ãŠããµã³ã¯ã¢ãã«ã¯ããå°ãæè»ã§ããããšãããããŸãã
ããããããã®ã³ã°ã®ãããªãã®ããããã¯ãéåæé²è¡äžããžãŒã€ã³ãžã±ãŒã¿ãŒãã®åãæ¿ãã§ãããããã«ãŠã§ã¢ã®ããé©åãªäŸã§ããïŒ
@ justin808
ã©ã¡ãã倧äžå€«ã§ãã åé·æ§ãå°ãªããã®ãšããããžã§ã¯ãã§ããŸãæ©èœãããã®ãéžæããŠãã ããã ç§ã®ææ¡ã¯ããµã³ã¯ã®äœ¿çšããå§ããŠããã¿ãŒã³ãç¹°ãè¿ãããŠããå Žåã¯ããããã«ã¹ã¿ã ããã«ãŠã§ã¢ã«æœåºããããšã§ãã ããªããããããæ··ããããšãã§ããŸãã
ããªã¬ãŒãããã¢ã¯ã·ã§ã³ã®ç¶æ ïŒèªã¿èŸŒã¿ãæåã倱æïŒãä»ã®ç¶æ ããåé¢ããããã®ActionStoreãäœæããŸããã ãããããããRedux / Fluxã®åºç€ã«åãããã©ããã¯ããããŸããã ç§ã¯ããã«ã€ããŠstackoverflowã«æçš¿ããŸããã
@gabrielgiussi https://github.com/acdlite/redux-promiseããå·ã«Promiseãä¿åããªããŠããå¿ èŠãªããšãéæã§ãããšæããŸãã ç¶æ ã¯åžžã«ã·ãªã¢ã«åå¯èœã§ãããšæ³å®ãããŠããŸãã
@wmertensã¢ããã€ã¹ãããããšãã ãªããžããªã確èªããŸããããªãç§ã®ç¶æ ãã·ãªã¢ã«åã§ããªãã®ã§ããïŒ ãããšãç§ã泚æããããã ãã«ãããèšãã®ã§ããïŒ
@gabrielgiussiããŸãããèŠãŠããŸããã§ããããããªããããã ã£ãããã§ã
çŽæãæ©èœãåºã«çœ®ãã ãããã«ããããã®ãããžã§ã¯ã
ç§ãããŸãããã¯ãã ãšæããŸãã
æã2015幎8æ10æ¥ã«ã¯ãåå19æ15 gabrielgiussi [email protected]ã¯æžããŸããïŒ
@wmertenshttps ïŒ//github.com/wmertensã¢ããã€ã¹ãããããšãã ããŸã
ãªããžããªãèŠãŠãã ãããããªãç§ã®ç¶æ ã¯ã·ãªã¢ã«åã§ããªãã®ã§ããïŒ ãããã¯ãããªã
ç§ã泚æããããã ãã«ãããèšããŸããïŒâ
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/gaearon/redux/issues/99#issuecomment-129531103 ã
ãããŒã
ïŒã¢ãã€ã«ã§å
¥åãç°¡æœããèšãèš³ïŒ
å®éãç§ãã«ã¹ã¿ã Actionãªããžã§ã¯ããé 眮ããã¹ãã¢ã§ã¯ããããã¯åçŽãªå±æ§ïŒidãstateãpayloadïŒãšPromiseãäœæããŠè¿ãã¢ã¯ã·ã§ã³ããªã¬ãŒãå«ãImmutable.Recordã§ãããããPromiseãã¹ãã¢ã«é 眮ããŠããŸããã ããããç§ã¯ããããã©ããå¥ã®å Žæã§äœããå£ããŠããã§ããããjeã @wmertensã«æè¬ããŸãã
@gabrielgiussi
ãããŠãPromiseãäœæããŠè¿ãã¢ã¯ã·ã§ã³ããªã¬ãŒ
é¢æ°ãã·ãªã¢ã«åã§ããªããã®ãç¶æ ã«ããªãã§ãã ããã
ãããã ç§ã¯èšã£ãŠã¿ãŸãã
PromiseãäœæããŠè¿ãé¢æ°ããªã¬ãŒ
ç§ãå®éã«ã¹ãã¢ã«å ¥ããŠããã®ã¯Actionãªããžã§ã¯ãã§ãïŒååã¯æé«ã§ã¯ãããŸããã§ããïŒïŒ
export default class Action extends Immutable.Record({state: 'idle', api: null, type: null, payload: null, id: null}){
load(){
return this.set('state','loading');
}
succeed(){
return this.set('state','succeeded');
}
fail(){
return this.set('state','failed');
}
ended(){
return this.get('state') != 'loading' && this.get('state') != 'idle';
}
endedWithSuccess(){
return this.get('state') == 'succeeded';
}
endedWithFailure(){
return this.get('state') == 'failed';
}
trigger() {
return (dispatch) => {
dispatch({type: this.get('type') + '_START', action: this});
let payload = this.get('payload');
this.get('api').call({dispatch,payload}).then((result) => {
dispatch({type: this.get('type') + '_SUCCESS',id: this.get('id'), result: result.result});
}).catch((result) => {
dispatch({type: this.get('type') + '_FAIL',id: this.get('id'), result: result.result});
});
}
}
}
ãã®åé¡ã解決ããããã®ã©ã€ãã©ãªãäœæããŸããïŒïŒ539ãåç §ïŒãããã¯ãä¿çäžã®ã¢ã¯ã·ã§ã³ã«å¯ŸããŠããã«ãŠã§ã¢ãçŽæãè¿ãããã«ããããããã¹ãŠã®çŽæã解決ãããã®ãåŸ ã€ããšã§æ©èœããŸãã
@gaearonããªããæžãããã®ã³ãŒãhttps://github.com/rackt/redux/issues/99#issuecomment-112212639 ã
ããã¯reduxã©ã€ãã©ãªã«å«ãŸããŠãããã®ã§ããããããšãæåã§äœæããå¿ èŠããããã®ã§ããïŒ ãããæ°ãã質åã§ããå Žåã¯ç³ãèš³ãããŸããããReact / FluxïŒReduxïŒã«å ¥ãã ãã§ãã ãã®ãã¥ãŒããªã¢ã«ãå§ããã°ããhttps://github.com/happypoulp/redux-tutorial
@ banderson5144
å«ãŸããŠããŸããã äœãã§ããããç¥ãããã ãã«ãããŸãããå¥ã®æ¹æ³ã§èªç±ã«è¡ãããšãã§ããŸãã
åæ§ã®ãã®ãhttps://github.com/pburtchaell/redux-promise-middlewareãšããŠå
¬éãããŸãã
ãã®æçšãªæ å ±ãããããšãã ç§ã¯åºããªã»ããããããšã«ã€ããŠããªãã®é è³ãéžã³ããã£ã-
ã©ããã£ãŠããã解決ããã®ã§ãã/ã©ã®ããã«ã¢ã€ãã¢ããããŸããïŒ ä»£ããã«ããŠãŒã¶ãŒããšã«æ°ããã¹ãã¢ãæ©èœããŸããïŒ
ãµãŒããŒã¬ã³ããªã³ã°ã«ã€ããŠè©±ããŠããã®ã§ããïŒ ãªã¯ãšã¹ãããšã«æ°ããã¹ãã¢ãäœæããŸãã ããã¥ã¡ã³ãã«ãµãŒããŒã¬ã³ããªã³ã°ã®ã¬ã€ãããããŸãã
ããããšãç§ã¯ãããããŸã
ç解ããããšããåŸâŠ
ããã¯ãã€ãŒããããŸããïŒ ïŒä»ã®èª°ããããããŠããªãããã§ãâç§ã¯æããŸãïŒ
// server.js
app.use(function (req, res) {
match({âŠ}, function (error, redirectLocation, renderProps) {
âŠ
if (renderProps) {
const store = configureStore();
const promises = renderProps.components.map(function (component, index) {
if (typeof component.fetchData !== 'function') {
return false;
}
return component.fetchData(store.dispatch);
});
Promise.all(promises).then(function () {
res.status(200).send(getMarkup(store, renderProps));
});
}
})
});
// home.js
export class Home extends Component {
static fetchData() {
return Promise.all([
dispatch(asyncAction);
]);
},
componentDidMount() {
const { dispatch } = this.props;
Home.fetchData(dispatch);
}
}
export default connect()(Home);
// action.js
export function asyncAction() {
return (dispatch, getState) => {
dispatch(request);
return fetch(âŠ)
.then(response => response.json())
.then(data => dispatch(requestSuccess(data)))
;
}
}
ãŸãã @ mattybowã®è³ªåhttps://github.com/rackt/redux/issues/99#issuecomment -112980776ïŒããŒã¿ãã§ããã管çãããã¹ããããã³ã³ããŒãã³ãïŒã®è§£æ±ºçãèŠã€ããããšããŠããŸãããããã®ãããªæåã¯ãããŸããã§ããïŒããã§ã¯ãããŸããã§ããïŒã componentWillMount
ãããããã¹ãåéããæ¹æ³ã確èªããŠãã ããïŒã
@chemoishç§ã¯ãŸããreactãšreduxã䜿çšããŠãµãŒããŒåŽã®ã¬ã³ããªã³ã°ã«é ã
ããªãã®ãœãªã¥ãŒã·ã§ã³ã¯ãããéæããã®ã«éåžžã«è¯ãããã§ãã ããã¯ããªãã®ããã«ããŸããããŸãããïŒ ããããšã
ç·šéïŒãcomponentDidMountãããµãŒããŒã§ã¬ã³ããªã³ã°ããããšãã«ã¯ã©ã€ã¢ã³ãã§å床ããªã¬ãŒãããªãã®ã¯æ£ããã§ããïŒ
@ ms88privatç§ã¯ãŸã ãœãªã¥ãŒã·ã§ã³ã«ã€ããŠå€ãã®ãã£ãŒãããã¯ãåŸãŠãããããã®éçããã¹ãããŠããŸããã
ãã ããäžèšã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãåããŒãžããã®ãã¹ãŠã®åã³ã³ããŒãã³ãã®ããŒã¿ãç¥ã£ãŠããå¿ èŠããããŸãã ãã¹ããããã³ã³ããŒãã³ããããŒã¿ç®¡çèªäœã«ã€ããŠå¿é ããããšã«ã€ããŠã¯ãæ·±ãæãäžããŠããŸããïŒãã¹ããããpromiseãåéããããïŒã
ããã¯ããªããæåŸ ããããšãããŠããããã«èŠããã®ã§ãä»ã®ãšããç§ã«ãšã£ãŠã¯ååã§ãã
componentDidMount
ãå床ããªã¬ãŒãããŸãïŒhttps://facebook.github.io/react/docs/component-specs.html#mounting-componentdidmountãåç
§ïŒã ããŒãºã«åã£ããã®æ¹æ³ãŸãã¯å¥ã®ã©ã€ããµã€ã¯ã«æ¹æ³ã䜿çšã§ããŸãã
ãããåé¿ããã«ã¯ãã¹ãã¢ããã§ã«ãã£ã±ãã«ãªã£ãŠããå ŽåïŒãŸãã¯é©åãšæãããããžãã¹ããžãã¯ïŒã«fetch
ã³ãŒããå®è¡ãããªãããã«ããŸãã
ç§ã話ããŠããããšã®ã¢ã€ãã¢ã«ã€ããŠã¯ã httpsïŒ//github.com/reactjs/redux/blob/master/examples/async/actions/index.js#L47ã調ã¹ãŠ
@chemoish
ã¹ãã¢ããã§ã«ãã£ã±ãã®å Žåã«ãã§ããã³ãŒããå®è¡ãããªãããã«ããããšã§ããããåé¿ããŸã
ããããŸãããããããŸããã ããããšãã
ãã ããäžèšã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãåããŒãžããã®ãã¹ãŠã®åã³ã³ããŒãã³ãã®ããŒã¿ãç¥ã£ãŠããå¿ èŠããããŸãã
ãã¶ãç§ã¯ããªãã®ãœãªã¥ãŒã·ã§ã³ãèªã¿ééããŸããããããã¯ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ã«é¢ä¿ãªãå¿ èŠãªèŠä»¶ã§ã¯ãããŸãããïŒ ïŒããšãã°ãSPAã§ãã£ãŠããçŸåšã®ã«ãŒãã§æŽæ°ãããšãåãç¶æ ã«ãªãã¯ãã§ãïŒ
ããã¯å¯èœã§ãããäœããã®çç±ã§ããã¹ããããã³ã³ããŒãã³ããç¬èªã®ããŒã¿ãã§ããã管çããå¿ èŠãããå ŽåããããŸãã
ããšãã°ãå€ãã®ããŒãžã§ç¹°ãè¿ãããã³ã³ããŒãã³ãã§ãããåããŒãžã«ã¯ããŒã¿ãã§ããã®å¿ èŠæ§ãããŸããããŸããã
@chemoishåãããŒãžã«ãããã©ããã¯ããããŸããã ç§ã®èŠè§£ã説æããããšæããŸãã
ããšãã°ã3ã€ã®ãã¹ããããã³ã³ããŒãã³ããååŸããŸããã
ããããã«ç¬èªã®ãcomponentDidMountãã¡ãœããããããç¬èªã®dataFetching宣èšïŒéçãªdataFetchingã¡ãœãããä»ããŠã¢ã¯ã·ã§ã³ããã£ã¹ãããããŸãïŒããããŸãã
ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ããªããçŸåšã®URLãæŽæ°ãããšãã³ã³ããŒãã³ããããŠã³ããããå¿ èŠãªãã¹ãŠã®ããŒã¿ãåŸã§ããŒãããããã«å¿ èŠãªãã¹ãŠã®ã¢ã¯ã·ã§ã³ãããªã¬ãŒãããŸãã
ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ã§ã¯ã match
é¢æ°ãšrenderProps
ã3ã€ã®ã³ã³ããŒãã³ããã¹ãŠãæœåºããããããã¹ãŠã®éçdataFetchingã¡ãœããã«ã¢ã¯ã»ã¹ã§ããŸããããã«ãããã«å¿
èŠãªãã¹ãŠã®ããŒã¿ããã§ããã§ããŸããæåã®ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ïŒ
æäŸãããäŸããmatch function
ãžã®åç
§ããããŸããïŒ THXã
@ ms88privat renderProps.components
ã¯ã«ãŒã¿ãŒã³ã³ããŒãã³ãã®é
åã§ããããã以äžæ·±ãã¯ãªããŸããã @chemoishã¯ã圌ã®å®è£
ã§ã¯ãããæ·±ãã³ã³ããŒãã³ãã§ã®ããŒã¿ãã§ããã®ããŒãºã説æã§ããªãããšãæå³ããŸããã
@DominicTobias thxããã®åé¡ã®è§£æ±ºçã¯ãããŸããïŒ ãã¹ãããããã¹ãŠã®ã³ã³ããŒãã³ããååŸããå¯èœæ§ã¯ãããŸããïŒ
ããããããã¯åœ¹ç«ã€ã§ããããïŒ https://github.com/gaearon/react-side-effect
ãã¹ããããèŠçŽ ãããã¹ãŠã®ã¡ã¿ã¿ã°ãåéããããã«äœ¿çšãããŸãïŒ https ïŒ
ãã®è°è«ã«åã³ã¶ã€ãã£ãŠç³ãèš³ãããŸããããç§ã¯æè¿ãéåæã¢ã¯ã·ã§ã³ã§ç¶æ ãäºåå ¥åãããšããåãåé¡ã«ééããŸããã
@erikrasããã€ã©ãŒãã¬ãŒããããžã§ã¯ããredux-async-connectã«ç§»åããããšãããããŸãã 誰ããå¥ã®è§£æ±ºçãèŠã€ããã®ã ãããïŒ
@vtambourineç§ã¯https://github.com/markdalgleish/redialãèŠãŠããŸãã
ã¯ããç§ã¯ããã調ã¹ãŸããã ããããããŒã¿ã確èªããæ¹æ³ãããããŸããã§ãã
ã³ãŒããnã«ååæåããåŸãããã¯ããããã§ããã¯2åå®è¡ãããŸãã
ã¯ã©ã€ã¢ã³ãã
ÐÑã§ã¯ã2016幎3æ18æ¥ã å€09æ54æãã·ã§ãŒã³ã»ãã»ãœã³[email protected]
æžããŸããïŒ
@vtambourinehttps ïŒ//github.com/vtambourineç§ãèŠãŠãã
https://github.com/markdalgleish/redialããã¯éåžžã«åœ¹ç«ã¡ãŸãâ
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/reactjs/redux/issues/99#issuecomment -198517067
ãŸãã誰ãããã®èª²é¡ã®å®å®ãã解決çãèŠã€ãããã©ãããç¥ãããã§ãã ç§ã¯@erikrasã®å®åæã倧奜ã@ vtambourineãè¿°ã¹ãããã«ãããã¯å®å®ããé·æçãªè§£æ±ºçã§ã¯ãªãããã«æãããredux-async-connectã«ç§»è¡ããŸããïŒ ïŒ81 redux-async-connectã¯æ»ãã§ããŸããïŒ ã
@vtambourine https://github.com/makeomatic/redux-connectã§å ¥æã§ãããã©ãŒã¯ããããæå ¥ããè¡ãå±ããŠããŸãã ããã€ãã®å€æŽãå ããåæ§ã®APIããããŸããèå³ãããå Žåã¯ããã§ãã¯ããŠãã ããã
@gaearonãè¿°ã¹ãããã«ãããã«ãŠã§ã¢ã䜿çšããreduxãœãªã¥ãŒã·ã§ã³ã«é¢å¿ã®ãã人ã®ããã«ããã®ææ³ãå®è£ ããã³ã³ããŒãã³ãèªäœããµãŒããŒåŽã§å¿ èŠãªããŒã¿ãèŠæ±ã§ããããã«ãããµã³ãã«ãããžã§ã¯ãããããŸãã
https://github.com/peter-mouland/react-lego-2016#redux -with-promise-middleware
ãã®ã¢ãããŒãã§ã¢ã¯ã·ã§ã³ã¯ãªãšãŒã¿ãŒããŠããããã¹ãããæ¹æ³ã¯ïŒ
æãåèã«ãªãã³ã¡ã³ã