asyncアクションがあり、REST APIからデータをフェッチします:
export const list = (top, skip) => dispatch => {
dispatch({ type: 'LIST.REQUEST' });
$.get(API_URL, { top: top, skip: skip })
.done((data, testStatus, jqXHR) => {
dispatch({ type: 'LIST.SUCCESS', data: data });
});
};
skip
状態を変更するsyncアクション:
export const setSkip = (skip) => {
return {
type: 'LIST.SET_SKIP',
skip: skip
};
};
top = 10, skip = 0
の初期状態。コンポーネント内:
class List extends Component {
componentDidMount() {
this.list();
}
nextPage() {
let top = this.props.list.top;
let skip = this.props.list.skip;
// After this
this.props.onSetSkip(skip + top);
// Here skip has previous value of 0.
this.list();
// Here skip has new value of 10.
}
list() {
this.props.List(this.props.list.top, this.props.list.skip);
}
render () {
return (
<div>
<table> ... </table>
<button onClick={this.nextPage.bind(this)}>Next</button>
</div>
);
}
}
ボタンNextが最初にクリックされたとき、非同期アクションを使用するskip
の値は変更されていません。 syncアクションの後にアクションをディスパッチするにはどうすればよいですか?
返信いただきありがとうございますが、私はこのようにしました:
let top = this.props.list.top;
let skip = this.props.list.skip;
let newSkip = skip + top;
this.props.onList(top, newSkip);
this.props.onSetSkip(newSkip);
最初に新しいskip
を計算し、この新しい値で非同期アクションをディスパッチします。次に、synsアクションをディスパッチし、skip
状態を更新します。
redux thunk を使用している場合は、簡単に組み合わせることができます。アクション作成者がアクションの代わりに関数を返すことができるミドルウェアです。
アクションクリエーターをチェーン化する必要がなく、両方を実行するだけでよい場合、ソリューションは今はうまく機能しているかもしれません。
this.props.onList(top, newSkip);
this.props.onSetSkip(newSkip);
チェーンが必要な場合(同期的に呼び出す)、または最初にディスパッチされたアクションのデータから待機する場合、これがお勧めです。
export function onList(data) {
return (dispatch) => {
dispatch(ONLIST_REQUEST());
return (AsyncAPICall)
.then((response) => {
dispatch(ONLIST_SUCCESS(response.data));
})
.catch((err) => {
console.log(err);
});
};
}
export function setSkip(data) {
return (dispatch) => {
dispatch(SETSKIP_REQUEST());
return (AsyncAPICall(data))
.then((response) => {
dispatch(SETSKIP_SUCCESS(response.data));
})
.catch((err) => {
console.log(err);
});
};
}
export function onListAndSetSkip(dataForOnList) {
return (dispatch) => {
dispatch(onList(dataForOnList)).then((dataAfterOnList) => {
dispatch(setSkip(dataAfterOnList));
});
};
}
同期アクションの後にアクションをディスパッチする代わりに、リデューサーから関数を呼び出すことができますか?
したがって、このフローに従います。
同期アクション呼び出し->レデューサー呼び出し--->ケース関数(レデューサー)--->ケース関数(レデューサー)
おそらくあなたのためにこれである通常のフローの代わりに:
同期アクション呼び出し->レデューサー呼び出し
レデューサーを分割する にこのガイドに従ってください。
ただし、ディスパッチしたいアクションに副次的な影響がある場合、正しい方法はサンクを使用することで、アクションの後にアクションをディスパッチできます。
サンク の例:
export const setSkip = (skip) => {
return (dispatch, getState) => {
dispatch(someFunc());
//Do someFunc first then this action, use getState() for currentState if you want
return {
type: 'LIST.SET_SKIP',
skip: skip
};
}
};
これも確認してください redux-sequence-action