面试题答案
一键面试创建action
- 定义action类型:在Redux中,action是一个普通JavaScript对象,必须有一个
type
字段来表示动作的类型。通常将所有action类型定义在一个单独的文件中,便于管理。例如:
// actionTypes.js
export const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
export const FETCH_DATA_FAILURE = 'FETCH_DATA_FAILURE';
- 创建action创建函数:action创建函数是返回action对象的函数。对于同步操作,简单返回包含
type
及相关数据的对象。对于异步操作,通常使用中间件(如redux - thunk
或redux - saga
)来处理。以redux - thunk
为例,action创建函数可以返回一个函数而不是普通对象。
// actions.js
import { FETCH_DATA_REQUEST, FETCH_DATA_SUCCESS, FETCH_DATA_FAILURE } from './actionTypes';
import axios from 'axios';
export const fetchDataRequest = () => ({
type: FETCH_DATA_REQUEST
});
export const fetchDataSuccess = (data) => ({
type: FETCH_DATA_SUCCESS,
payload: data
});
export const fetchDataFailure = (error) => ({
type: FETCH_DATA_FAILURE,
payload: error
});
export const fetchData = () => {
return async (dispatch) => {
dispatch(fetchDataRequest());
try {
const response = await axios.get('/api/data');
dispatch(fetchDataSuccess(response.data));
} catch (error) {
dispatch(fetchDataFailure(error.message));
}
};
};
创建reducer
- 定义初始状态:reducer是一个纯函数,接收当前状态和action作为参数,返回新的状态。首先要定义初始状态,例如:
// initialState.js
const initialState = {
data: null,
loading: false,
error: null
};
export default initialState;
- 编写reducer函数:根据action的
type
来处理不同的状态变化。
// reducer.js
import { FETCH_DATA_REQUEST, FETCH_DATA_SUCCESS, FETCH_DATA_FAILURE } from './actionTypes';
import initialState from './initialState';
const dataReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_DATA_REQUEST:
return {
...state,
loading: true
};
case FETCH_DATA_SUCCESS:
return {
...state,
loading: false,
data: action.payload,
error: null
};
case FETCH_DATA_FAILURE:
return {
...state,
loading: false,
data: null,
error: action.payload
};
default:
return state;
}
};
export default dataReducer;
连接组件(使用connect,这里以react - redux v6及之前版本为例,v7+推荐使用useSelector和useDispatch)
- 创建store:在应用入口处,使用
createStore
来创建Redux store,并传入reducer。如果使用中间件,如redux - thunk
,需要通过applyMiddleware
来应用。
// store.js
import { createStore, applyMiddleware } from'redux';
import thunk from'redux - thunk';
import dataReducer from './reducer';
const store = createStore(dataReducer, applyMiddleware(thunk));
export default store;
- 连接组件:使用
connect
函数将React组件连接到Redux store。connect
函数接收两个参数:mapStateToProps
和mapDispatchToProps
。
import React from'react';
import { connect } from'react - redux';
import { fetchData } from './actions';
const MyComponent = ({ data, loading, error, fetchData }) => {
React.useEffect(() => {
fetchData();
}, [fetchData]);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
<h1>Data</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};
const mapStateToProps = (state) => ({
data: state.data,
loading: state.loading,
error: state.error
});
const mapDispatchToProps = {
fetchData
};
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
处理异步操作
- 使用redux - thunk:如上述
actions.js
中fetchData
函数所示,redux - thunk
允许action创建函数返回一个函数。在这个函数中,可以进行异步操作(如网络请求),并在适当的时候通过dispatch
来分发不同的action,以更新store中的状态。例如,在发起网络请求前分发FETCH_DATA_REQUEST
action使loading
状态为true
,请求成功后分发FETCH_DATA_SUCCESS
action更新数据并将loading
设为false
,请求失败时分发FETCH_DATA_FAILURE
action设置错误信息并将loading
设为false
。 - 使用redux - saga:
redux - saga
使用生成器函数来管理副作用(如异步操作)。首先安装redux - saga
,然后创建一个saga文件。
// saga.js
import { call, put, takeEvery } from'redux - saga/effects';
import axios from 'axios';
import { FETCH_DATA_REQUEST, FETCH_DATA_SUCCESS, FETCH_DATA_FAILURE } from './actionTypes';
function* fetchDataSaga() {
try {
yield put({ type: FETCH_DATA_REQUEST });
const response = yield call(axios.get, '/api/data');
yield put({ type: FETCH_DATA_SUCCESS, payload: response.data });
} catch (error) {
yield put({ type: FETCH_DATA_FAILURE, payload: error.message });
}
}
export function* dataSaga() {
yield takeEvery('FETCH_DATA', fetchDataSaga);
}
在store.js
中应用saga:
import { createStore, applyMiddleware } from'redux';
import createSagaMiddleware from'redux - saga';
import dataReducer from './reducer';
import { dataSaga } from './saga';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(dataReducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(dataSaga);
export default store;
通过这些步骤,可以完整地使用Redux处理React应用中的跨组件事件通信及异步操作。