==================== TLDR ==========================
@markerikson(请参阅已接受的答案)亲切地指出了当前的解决方案和未来的解决方案。
编辑:2020 年 11 月 15 日:链接到文档以在 Slice 中使用 Async Thunk
RTK确实支持使用 thunk 中间件的 reducer 中的 thunk(参见答案)。
在 1.3.0 版本(目前 alpha 于 2020 年 2 月)中,有一个辅助方法createAsyncThunk() createAsyncThunk将提供一些有用的功能(即根据 Promise的状态触发 3 个“扩展”reducer)。
========================原始帖子 2020 年 2 月====================== ====
我对 Redux 很陌生,遇到了 Redux Toolkit (RTK) 并希望实现它提供的更多功能(或者在这种情况下可能没有?)(2020 年 2 月)
我的应用程序分派到通过创建的减速器切片createSlice({})(请参阅createSlice api docs)
到目前为止,这非常有效。我可以轻松地使用内置dispatch(action)和useSelector(selector)调度动作,并在我的组件中很好地接收/响应状态变化。
我想使用 axios 的异步调用从 API …
我读到Redux Thunk是管理异步操作/请求的可靠方法.没有太多关于通过其他行动调度行动的事情.
如何调度同步动作?我不确定thunk方法的性能问题,但是我可以在其他动作创建者中调度动作而不在其中定义函数吗?
在我看来,使用redux thunk对于这种需求是不必要的.
我在其他问题中看到了相互矛盾(或者只是让我感到困惑)关于getState在一个动作中使用是否可接受的答案,而且我已经看过很多次它被称为反模式.对我来说,它似乎工作得很好,但如果我们不使用它,最好的做法是什么getState?
我getState在一个thunk中使用来过滤当前连接到某些模拟数据并被拉入应用程序状态的用户数组.
这是我的行动代码:
export const accountLogInSuccess = user => ({
type: types.ACCOUNT_LOG_IN_SUCCESS,
user,
});
export const accountLogOutSuccess = () => ({
type: types.ACCOUNT_LOG_OUT_SUCCESS,
});
export const accountCheckSuccess = () => ({
type: types.ACCOUNT_CHECK_SUCCESS,
});
export const accountCheck = () => (
(dispatch, getState) => {
dispatch(ajaxCallBegin());
return apiAccount.accountCheck().then((account) => {
if (account) {
const user = findByUID(getState().users, account.uid);
dispatch(accountLogInSuccess(user));
toastr.success(`Welcome ${user.nameFirst}!`);
} else {
dispatch(accountLogOutSuccess());
}
dispatch(accountCheckSuccess());
}).catch((error) => {
dispatch(ajaxCallError(error));
toastr.error(error.message);
throw (error); …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我的reactjs应用程序中应用redux.由于这些错误,我无法继续:
我确信我已经安装了所需的所有依赖项.这是我的package.json的相关部分
"dependencies": {
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-promise": "^0.5.3",
"redux-thunk": "^2.2.0",
}
Run Code Online (Sandbox Code Playgroud)
这是我实现redux的index.js的一部分
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import reducers from './reducers';
const logger = createLogger();
const store = createStore(reducers,
applyMiddleware(
thunkMiddleware, logger
)
)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud) 所以这是我正在玩的代码
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import axios from 'axios'
const initialState = {
user: {},
requesting: false,
err: null
}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'REQ_USER_INIT': return { ...state, requesting: true }
case 'REQ_USER_DATA': return { ...state, requesting: false, user: action.user }
case 'REQ_USER_ERR': return { ...state, requesting: false, err: action.err }
}
return state;
}
const logger = (store) => (next) => (action) = … 我不明白需要什么redux-thunk.据我所知,a thunk是一个返回函数的函数.在我看来,包装的表达式和中间件的使用可以做更多的工作来模糊正在发生的事情.取自redux-thunk的示例代码
import thunk from 'redux-thunk';
// Note: this API requires redux@>=3.1.0
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
// Meet thunks.
// A thunk is a function t hat returns a function.
// This is a thunk.
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 …Run Code Online (Sandbox Code Playgroud) 我得到这个错误
_react.default.memo不是函数
和wrapWithConnect。
这是一个react-native项目,在使用connect函数将调度程序连接到我的react组件之前,它运行良好:
套件版本:
"react": "16.5.0",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
Run Code Online (Sandbox Code Playgroud)
码
const mapDispatchToProps = dispatch => {
return {
sendEmail: (email, navigateMap) => dispatch(sendEmail, navigateMap))
export default connect(null, mapDispatchToProps)(Login)
Run Code Online (Sandbox Code Playgroud) 我昨天刚开始使用 redux,在阅读了不同的库后,我决定使用 RTK 的切片路线。
对于我的异步,我决定使用 RTK 查询,而不是使用 createAsyncThunk,并且我有一个关于从另一个切片访问状态的正确方法的问题。
slice1 包含一些用户数据,例如:
export const initialState: IUserState = {
name: 'example',
id: null,
};
Run Code Online (Sandbox Code Playgroud)
在我的 slice2 中,我有一个函数想要执行getSomethingByUserId(id)和我当前的实现之类的操作:
interface IApiResponse {
success: true;
result: IGotSomethingData[];
}
const getsomethingSlice: any = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: 'https://someapibase',
}),
endpoints(builder) {
return {
fetchAccountAssetsById: builder.query<IApiResponse, null>({
query() {
console.log('store can be called here', store.getState().user.id);
return `/apipath?id=${store.getState().user.id}`;
},
}),
};
},
});
export default getsomethingSlice;
export const { useFetchAccountAssetsByIdQuery } = getsomethingSlice;
Run Code Online (Sandbox Code Playgroud)
正如我在某处读到的,markikson 提到导入 …
当我将操作连接到extraReducers时发生此错误 我的代码是
export const fetchCountries = createAsyncThunk(
`country`,
async (organizationId: string) => {
export const saveCountry = createAsyncThunk(
`country`,
async ({ } => {})
const regions = createSlice({
name,
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchCountries.pending, isFetching);
builder.addCase(fetchCountries.rejected, error);
builder.addCase(fetchCountries.fulfilled, (state, action) => {});
builder.addCase(saveCountry.pending, isFetching);
builder.addCase(saveCountry.rejected, error);
builder.addCase(saveCountry.fulfilled, (state, {payload}) => {});
Run Code Online (Sandbox Code Playgroud)
如果我运行我会收到此错误:
Error: addCase cannot be called with two reducers for the same action type
我在我的行动中使用axios.我需要知道这是否是正确的做法.
actions/index.js ==>
import axios from 'axios';
import types from './actionTypes'
const APY_KEY = '2925805fa0bcb3f3df21bb0451f0358f';
const API_URL = `http://api.openweathermap.org/data/2.5/forecast?appid=${APY_KEY}`;
export function FetchWeather(city) {
let url = `${API_URL}&q=${city},in`;
let promise = axios.get(url);
return {
type: types.FETCH_WEATHER,
payload: promise
};
}
Run Code Online (Sandbox Code Playgroud)
reducer_weather.js ==>
import actionTypes from '../actions/actionTypes'
export default function ReducerWeather (state = null, action = null) {
console.log('ReducerWeather ', action, new Date(Date.now()));
switch (action.type) {
case actionTypes.FETCH_WEATHER:
return action.payload;
}
return state;
}
Run Code Online (Sandbox Code Playgroud)
然后将它们组合在rootReducer.js ==>中
import { combineReducers …Run Code Online (Sandbox Code Playgroud) redux-thunk ×10
redux ×9
reactjs ×6
javascript ×4
react-redux ×4
axios ×1
getstate ×1
react-native ×1
rtk-query ×1
typescript ×1