I am new to dvajs. I am using React 17,x, Typescript 4.2.3, antd 4.15.0, umi 3.4.7
The problem.
If I navigate to the /s/
page, the code should get some categories from the API and make another request to the server, displaying them on some pages at this time. But the moment the search effect is called, the categories are empty, so I try to call the getCategories action again. But the categories are still empty. How do you get the result from action in another action? Maybe there is some kind of dispatch chain?
The code is provided below
import { fetchCategories, makeSearch } from '@/services/search';
import { CategoriesModelStateSelector, Subscription } from '@@/plugin-dva/connect';
import { Reducer, Effect } from 'umi';
export type SearchModelState = {
searchResults: Provider[]
categories: Category[]
}
export type SearchModelType = {
namespace: string;
state: SearchModelState;
effects: {
getCategories: Effect;
search: Effect;
};
reducers: {
setCategories: Reducer
setSearchResults: Reducer
};
subscriptions: {
setup: Subscription
}
};
export type SearchModelStateSelector = {
search: SearchModelState
};
const SearchModel: SearchModelType = {
namespace: 'search',
state: {
categories: [],
searchResults: [],
},
effects: {
* getCategories({ payload }, { call, put, select }) {
const response = yield call(fetchCategories);
if (response) {
yield put({
type: 'setCategories',
payload: response,
});
}
},
* search({ payload }, { call, put, select }) {
let categories = yield select(({ categories: state }: CategoriesModelStateSelector) => state.categories);
// HERE categories are empty
console.log(categories);
yield put({
type: 'getCategories',
payload: {},
});
let catss = yield select(({ categories: state }: CategoriesModelStateSelector) => state.categories);
console.log(catss);
// HERE categories are still empty
const response = yield call(makeSearch, payload);
yield put({
type: 'setSearchResults',
payload: response,
});
},
},
reducers: {
setCategories(state, { payload }) {
return {
...state,
categories: response,
};
},
setSearchResults(state, { payload }) {
return {
...state,
searchResults: response,
};
},
},
subscriptions: {
setup({ dispatch, history }) {
// @ts-ignore
return history.listen(({ pathname, query }) => {
dispatch({ type: 'getCategories', payload: {} });
if (pathname === '/s' || pathname === '/s/') {
dispatch({ type: 'search', payload: query });
}
});
},
},
};
export default SearchModel;