【发布时间】:2020-02-23 19:53:52
【问题描述】:
我是 redux 的新手,我发现很难找到一个既使用异步调用又使用 typescript 的好指南。我试图自己弄清楚,但我有点卡住了。如果有人可以查看我的代码并就如何解决这个问题给我反馈和/或建议,我将不胜感激!
// types.ts file
export const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST';
export const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS';
export const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE';
^ 这里我定义了常量以保持一致性。
// userActions.ts
import { FETCH_USERS_FAILURE, FETCH_USERS_REQUEST, FETCH_USERS_SUCCESS } from './types';
import { Dispatch } from 'redux';
import axios, { AxiosResponse } from 'axios';
export interface UserProps {
id: number
name: string
email: string
}
export const fetchUsersRequest = () => {
return {
type: FETCH_USERS_REQUEST,
};
};
export const fetchUsersSuccess = (users: Array<UserProps>) => {
return {
type: FETCH_USERS_SUCCESS,
users: users,
};
};
export const fetchUsersFailure = (error: string) => {
return {
type: FETCH_USERS_FAILURE,
error: error,
};
};
export const fetchUsers = () => {
return (dispatch: Dispatch): Promise<unknown> => {
dispatch(fetchUsersRequest());
return axios.get('https://jsonplaceholder.typicode.com/users')
.then((response: AxiosResponse<UserProps[]>) => {
dispatch(fetchUsersSuccess(response.data));
return response.data;
})
.catch((error: string) => {
dispatch(fetchUsersFailure(error));
});
};
};
用户减速器
import { UserProps } from '../actions/userActions';
import { FETCH_USERS_FAILURE, FETCH_USERS_REQUEST, FETCH_USERS_SUCCESS } from '../actions/types';
interface Action {
type: string
payload: Array<UserProps> | string,
}
export interface initialStateProps {
loading: boolean,
users: Array<UserProps>
error: string
}
const initialState: initialStateProps = {
loading: false,
users: [],
error: '',
};
export const userReducer = (state = initialState, action: Action) => {
switch (action.type) {
case FETCH_USERS_REQUEST:
return {
...state,
loading: true,
};
case FETCH_USERS_SUCCESS:
return {
loading: false,
users: action.payload,
};
case FETCH_USERS_FAILURE:
return {
loading: false,
users: [],
error: action.payload,
};
default: {
return state;
}
}
};
export const getUsers = (state: initialStateProps) => state.users;
export const getUsersRequest = (state: initialStateProps) => state.loading;
export const getUsersFailure = (state: initialStateProps) => state.error;
然后对于我的项目,我使用connected-router 来帮助跟踪路线。
import { combineReducers } from 'redux';
import { History } from 'history';
import { connectRouter } from 'connected-react-router';
import { userReducer } from './userReducers';
export const createRootReducer = (history: History) => combineReducers({
router: connectRouter(history),
userReducer,
});
商店:
import { createBrowserHistory } from 'history';
import { applyMiddleware, compose, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger';
import { routerMiddleware } from 'connected-react-router';
import { createRootReducer } from './reducers';
export const history = createBrowserHistory();
const loggerMiddleware = createLogger();
export const configureStore = (preloadedState?: any) => {
const composeEnhancer: typeof compose = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
return createStore(
createRootReducer(history),
preloadedState,
composeEnhancer(
applyMiddleware(
routerMiddleware(history),
thunkMiddleware,
loggerMiddleware,
),
),
);
};
在应用程序中我使用这个:
const mapStateToProps = (state: initialStateProps) => ({
error: getUsersFailure(state),
users: getUsers(state),
loading: getUsersRequest(state)
});
const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({
fetchUsers: fetchUsers
}, dispatch);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(TopbarNav);
但是当我console.log(props); 我得到:
users: undefined
loading: undefined
error: undefined
编辑: 我在这里运行 fetchUsers:
const TopbarNav: React.FC = (props: any) => {
const [loading, setLoading] = React.useState(true);
const classes = useStyles();
useEffect(() => {
props.fetchUsers();
});
const handler = () => {
console.log({props});
};
};
我在这个问题中省略了渲染方法。
EDIT 2 更新了 useEffect 方法:
const [users, setUsers] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const classes = useStyles();
useEffect(() => {
setUsers(props.fetchUsers());
}, [users, props, loading]);
const handler = () => {
console.log(props.loading);
};
【问题讨论】:
-
你在哪里运行 fetchUsers()?
-
内部使用效果
-
您的代码看起来不错,也许我们遗漏了一些东西。处理这类事情的一种常见方法是隔离代码的每个组件。尝试将初始状态放入组件中,然后通过组件调用 redux 操作。
-
好的,我该怎么做?可以举个例子吗?
-
也许可以尝试通过 react 和 redux 扩展来调试。首先检查
redux extension以确保您调度操作并将数据保存到存储中。然后查看react extension,查看组件的props。 chrome.google.com/webstore/detail/redux-devtools/…chrome.google.com/webstore/detail/react-developer-tools/…
标签: reactjs redux react-redux redux-thunk react-props