从另一个商店切片中的一个商店切片调用一个 redux 操作
Calling one redux action from one store slice in another store slice
我是 redux 新手。在我的应用程序中,我使用了一些带有 redux thunk 的异步操作。
例如,我有此操作用于从 API:
加载电影
export const loadMovies = (url) => async (dispatch) => {
const response = await fetch(url);
const result = await response.json();
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
};
而且我有情况如果没有要加载的电影怎么办(在数据库中搜索没有给我结果)所以我想更新状态(它是另一个 redux 存储片)到 'no movies' 例如。并根据该状态呈现不同的组件。
所以我的新动作是这样的:
export const loadMovies = (url) => async (dispatch) => {
const response = await fetch(url);
const result = await response.json();
if (result) {
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
} else {
dispatch(updateStatus('no-movies')) // updateStatus is imported from another redux store slice
}
};
我想知道这样做是否可以。或者将操作从一个存储切片导入另一个存储切片是一种不好的做法。什么是处理这种情况的更好方法。
您不需要从另一个商店切片导入操作。您可以在多个存储切片的缩减器中处理相同的查询电影操作类型。有关详细信息,请参阅 Allow Many Reducers to Respond to the Same Action
例如
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
const GET_MOVIES_FULFILLED = 'GET_MOVIES_FULFILLED';
function moviesLoaded(totalPages, movies) {
return {
type: GET_MOVIES_FULFILLED,
payload: {
totalPages,
movies,
},
};
}
export const loadMovies = () => async (dispatch) => {
// const response = await fetch(url);
// const result = await response.json();
// mock result
const result = { total_pages: 0, results: [] };
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
};
const rootReducer = combineReducers({
sliceA(state = { totalPages: 0, movies: [] }, action) {
switch (action.type) {
case GET_MOVIES_FULFILLED:
return action.payload;
default:
return state;
}
},
sliceB(state = { status: '' }, action) {
switch (action.type) {
case GET_MOVIES_FULFILLED:
if (!action.payload.movies || !action.payload.movies.length) {
return {
status: 'no movies',
};
}
default:
return state;
}
},
});
const store = createStore(rootReducer, applyMiddleware(thunk));
store.dispatch(loadMovies() as any).then(() => {
console.log(store.getState());
});
输出:
{
sliceA: { totalPages: 0, movies: [] },
sliceB: { status: 'no movies' }
}
调度 GET_MOVIES_FULFILLED
操作,在 sliceA
和 sliceB
减速器中处理它。
如果没有电影,我们将sliceB
的状态设置为{status: 'no movies'}
。
我是 redux 新手。在我的应用程序中,我使用了一些带有 redux thunk 的异步操作。 例如,我有此操作用于从 API:
加载电影export const loadMovies = (url) => async (dispatch) => {
const response = await fetch(url);
const result = await response.json();
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
};
而且我有情况如果没有要加载的电影怎么办(在数据库中搜索没有给我结果)所以我想更新状态(它是另一个 redux 存储片)到 'no movies' 例如。并根据该状态呈现不同的组件。
所以我的新动作是这样的:
export const loadMovies = (url) => async (dispatch) => {
const response = await fetch(url);
const result = await response.json();
if (result) {
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
} else {
dispatch(updateStatus('no-movies')) // updateStatus is imported from another redux store slice
}
};
我想知道这样做是否可以。或者将操作从一个存储切片导入另一个存储切片是一种不好的做法。什么是处理这种情况的更好方法。
您不需要从另一个商店切片导入操作。您可以在多个存储切片的缩减器中处理相同的查询电影操作类型。有关详细信息,请参阅 Allow Many Reducers to Respond to the Same Action
例如
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
const GET_MOVIES_FULFILLED = 'GET_MOVIES_FULFILLED';
function moviesLoaded(totalPages, movies) {
return {
type: GET_MOVIES_FULFILLED,
payload: {
totalPages,
movies,
},
};
}
export const loadMovies = () => async (dispatch) => {
// const response = await fetch(url);
// const result = await response.json();
// mock result
const result = { total_pages: 0, results: [] };
const { total_pages: totalPages, results: movies } = result;
dispatch(moviesLoaded(totalPages, movies));
};
const rootReducer = combineReducers({
sliceA(state = { totalPages: 0, movies: [] }, action) {
switch (action.type) {
case GET_MOVIES_FULFILLED:
return action.payload;
default:
return state;
}
},
sliceB(state = { status: '' }, action) {
switch (action.type) {
case GET_MOVIES_FULFILLED:
if (!action.payload.movies || !action.payload.movies.length) {
return {
status: 'no movies',
};
}
default:
return state;
}
},
});
const store = createStore(rootReducer, applyMiddleware(thunk));
store.dispatch(loadMovies() as any).then(() => {
console.log(store.getState());
});
输出:
{
sliceA: { totalPages: 0, movies: [] },
sliceB: { status: 'no movies' }
}
调度 GET_MOVIES_FULFILLED
操作,在 sliceA
和 sliceB
减速器中处理它。
如果没有电影,我们将sliceB
的状态设置为{status: 'no movies'}
。