请求完成后触发 Redux 异步操作。为什么?
Redux async action triggered after request finished. Why?
我的异步操作有问题。我想在调用操作 fetchPosts() 时将 'loading' 状态设置为 true,在调用操作 fetchPostsSuccess() 或 fetchPostsFailiure() 时将 'loading' 状态设置为 false。
使用我当前的代码,除了 'loading' 当 fetchPosts() 收到来自服务器的响应时状态发生变化并且我想在请求开始时更改此状态外,它几乎可以正常工作。
这是显示我的步骤的简单代码。
我正在使用 axios 和 redux-promise (https://github.com/acdlite/redux-promise).
// actions
export function fetchPosts() {
const request = axios.get(`${API_URL}/posts/`);
return {
type: 'FETCH_POSTS',
payload: request,
};
}
export function fetchPostsSuccess(posts) {
return {
type: 'FETCH_POSTS_SUCCESS',
payload: posts,
};
}
export function fetchPostsFailure(error) {
return {
type: 'FETCH_POSTS_FAILURE',
payload: error,
};
}
// reducer
const INITIAL_STATE = {
posts: [],
loading: false,
error: null,
}
const postsReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case 'FETCH_POSTS':
return { ...state, loading: true, error: null };
case 'FETCH_POSTS_SUCCESS':
return { ...state, posts: action.payload, loading: false };
case 'FETCH_POSTS_FAILURE':
return { ...state, posts: [], loading: false, error: action.payload };
default:
return state;
}
}
const rootReducer = combineReducers({
postsList: postsReducer,
});
// store
function configureStore(initialState) {
return createStore(
rootReducer,
applyMiddleware(
promise,
),
);
}
const store = configureStore();
// simple Posts app
class Posts extends Component {
componentWillMount() {
this.props.fetchPosts();
}
render() {
const { posts, loading } = this.props.postsList;
return (
<div>
{loading && <p>Loading...</p>}
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
</div>
);
}
}
const mapStateToProps = state => ({
postsList: state.postsList,
});
const mapDispatchToProps = dispatch => ({
fetchPosts: (params = {}) => {
dispatch(fetchPosts())
.then((response) => {
if (!response.error) {
dispatch(fetchPostsSuccess(response.payload.data));
} else {
dispatch(fetchPostsFailure(response.payload.data));
}
});
},
});
const PostsContainer = connect(mapStateToProps, mapDispatchToProps)(Posts);
// main
ReactDOM.render((
<Provider store={store}>
<Router history={browserHistory}>
<Route path="posts" component={PostsContainer} />
</Router>
</Provider>
), document.getElementById('appRoot'));
有人可以指导我做错了什么吗?
原来是 'redux-promise' 包的问题。这个异步中间件没有 'pending' 承诺状态(称为 'optimistic update')。
它仅在 promise 已被解决或拒绝时才更改状态。
我应该使用允许 'optimistic updates'
的不同中间件
您的问题出在 redux-promise
。您应该使用 redux-thunk
而不是允许您 return 一个函数并分派多次。看看它 ;)!
我的异步操作有问题。我想在调用操作 fetchPosts() 时将 'loading' 状态设置为 true,在调用操作 fetchPostsSuccess() 或 fetchPostsFailiure() 时将 'loading' 状态设置为 false。
使用我当前的代码,除了 'loading' 当 fetchPosts() 收到来自服务器的响应时状态发生变化并且我想在请求开始时更改此状态外,它几乎可以正常工作。
这是显示我的步骤的简单代码。 我正在使用 axios 和 redux-promise (https://github.com/acdlite/redux-promise).
// actions
export function fetchPosts() {
const request = axios.get(`${API_URL}/posts/`);
return {
type: 'FETCH_POSTS',
payload: request,
};
}
export function fetchPostsSuccess(posts) {
return {
type: 'FETCH_POSTS_SUCCESS',
payload: posts,
};
}
export function fetchPostsFailure(error) {
return {
type: 'FETCH_POSTS_FAILURE',
payload: error,
};
}
// reducer
const INITIAL_STATE = {
posts: [],
loading: false,
error: null,
}
const postsReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case 'FETCH_POSTS':
return { ...state, loading: true, error: null };
case 'FETCH_POSTS_SUCCESS':
return { ...state, posts: action.payload, loading: false };
case 'FETCH_POSTS_FAILURE':
return { ...state, posts: [], loading: false, error: action.payload };
default:
return state;
}
}
const rootReducer = combineReducers({
postsList: postsReducer,
});
// store
function configureStore(initialState) {
return createStore(
rootReducer,
applyMiddleware(
promise,
),
);
}
const store = configureStore();
// simple Posts app
class Posts extends Component {
componentWillMount() {
this.props.fetchPosts();
}
render() {
const { posts, loading } = this.props.postsList;
return (
<div>
{loading && <p>Loading...</p>}
<ul>
{posts.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
</div>
);
}
}
const mapStateToProps = state => ({
postsList: state.postsList,
});
const mapDispatchToProps = dispatch => ({
fetchPosts: (params = {}) => {
dispatch(fetchPosts())
.then((response) => {
if (!response.error) {
dispatch(fetchPostsSuccess(response.payload.data));
} else {
dispatch(fetchPostsFailure(response.payload.data));
}
});
},
});
const PostsContainer = connect(mapStateToProps, mapDispatchToProps)(Posts);
// main
ReactDOM.render((
<Provider store={store}>
<Router history={browserHistory}>
<Route path="posts" component={PostsContainer} />
</Router>
</Provider>
), document.getElementById('appRoot'));
有人可以指导我做错了什么吗?
原来是 'redux-promise' 包的问题。这个异步中间件没有 'pending' 承诺状态(称为 'optimistic update')。
它仅在 promise 已被解决或拒绝时才更改状态。
我应该使用允许 'optimistic updates'
的不同中间件您的问题出在 redux-promise
。您应该使用 redux-thunk
而不是允许您 return 一个函数并分派多次。看看它 ;)!