面试题答案
一键面试1. Redux 相关设计
Reducer 设计思路
- 商品列表数据:在 reducer 中维护一个
productList
状态,用于存储商品列表数据。例如:
const initialState = {
productList: [],
// 其他可能的状态,如加载状态、错误信息等
loading: false,
error: null
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case 'FETCH_PRODUCT_LIST_SUCCESS':
return {
...state,
productList: action.payload,
loading: false
};
case 'FETCH_PRODUCT_LIST_FAILURE':
return {
...state,
loading: false,
error: action.payload
};
case 'FILTER_PRODUCT_LIST':
// 根据筛选条件过滤 productList
return {
...state,
productList: state.productList.filter(product => {
// 实现价格范围和品牌等筛选逻辑
if (action.payload.minPrice && product.price < action.payload.minPrice) {
return false;
}
if (action.payload.maxPrice && product.price > action.payload.maxPrice) {
return false;
}
if (action.payload.brand && product.brand!== action.payload.brand) {
return false;
}
return true;
})
};
default:
return state;
}
};
- 商品详情数据:维护一个
productDetail
状态用于存储商品详情。例如:
const detailInitialState = {
productDetail: null,
loading: false,
error: null
};
const detailReducer = (state = detailInitialState, action) => {
switch (action.type) {
case 'FETCH_PRODUCT_DETAIL_SUCCESS':
return {
...state,
productDetail: action.payload,
loading: false
};
case 'FETCH_PRODUCT_DETAIL_FAILURE':
return {
...state,
loading: false,
error: action.payload
};
case 'UPDATE_PRODUCT_DETAIL_CACHE':
// 处理缓存更新逻辑
return {
...state,
productDetail: {
...state.productDetail,
...action.payload
}
};
default:
return state;
}
};
Action 设计思路
- 商品列表:
FETCH_PRODUCT_LIST_REQUEST
:发起获取商品列表请求时的 action,用于设置加载状态为true
。FETCH_PRODUCT_LIST_SUCCESS
:获取商品列表成功时的 action,携带服务器返回的商品列表数据。FETCH_PRODUCT_LIST_FAILURE
:获取商品列表失败时的 action,携带错误信息。FILTER_PRODUCT_LIST
:用户进行筛选操作时的 action,携带筛选条件。
- 商品详情:
FETCH_PRODUCT_DETAIL_REQUEST
:发起获取商品详情请求时的 action,设置加载状态为true
。FETCH_PRODUCT_LIST_SUCCESS
:获取商品详情成功时的 action,携带商品详情数据。FETCH_PRODUCT_LIST_FAILURE
:获取商品详情失败时的 action,携带错误信息。UPDATE_PRODUCT_DETAIL_CACHE
:用于更新商品详情缓存的 action,携带需要更新的数据。
Middleware 设计思路
- 使用 Redux - Thunk:由于商品详情页有复杂的异步操作,如数据预加载等,Redux - Thunk 可以让 action 创建函数返回一个函数而不是一个普通对象。例如:
import { FETCH_PRODUCT_DETAIL_REQUEST, FETCH_PRODUCT_DETAIL_SUCCESS, FETCH_PRODUCT_DETAIL_FAILURE } from './actionTypes';
import api from '../api'; // 假设这是请求 API 的模块
export const fetchProductDetail = (productId) => {
return async (dispatch) => {
dispatch({ type: FETCH_PRODUCT_DETAIL_REQUEST });
try {
const response = await api.getProductDetail(productId);
dispatch({ type: FETCH_PRODUCT_DETAIL_SUCCESS, payload: response.data });
} catch (error) {
dispatch({ type: FETCH_PRODUCT_DETAIL_FAILURE, payload: error.message });
}
};
};
- 数据缓存中间件:对于商品详情的缓存更新,可以考虑自定义一个中间件。这个中间件可以在 action 触发时检查是否是更新缓存的 action,并执行相应的缓存更新逻辑。例如:
const cacheMiddleware = ({ getState, dispatch }) => {
return next => action => {
if (action.type === 'UPDATE_PRODUCT_DETAIL_CACHE') {
// 这里可以执行缓存更新的具体逻辑,比如更新本地存储等
}
return next(action);
};
};
2. React Hooks 使用方式
商品列表页
- 使用
useSelector
和useDispatch
:
import React from'react';
import { useSelector, useDispatch } from'react-redux';
import { FILTER_PRODUCT_LIST } from './actionTypes';
const ProductList = () => {
const productList = useSelector(state => state.productReducer.productList);
const loading = useSelector(state => state.productReducer.loading);
const error = useSelector(state => state.productReducer.error);
const dispatch = useDispatch();
const handleFilter = (filter) => {
dispatch({ type: FILTER_PRODUCT_LIST, payload: filter });
};
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
{/* 筛选条件输入组件 */}
<input type="number" placeholder="Min Price" onChange={(e) => handleFilter({ minPrice: parseInt(e.target.value) })} />
<input type="number" placeholder="Max Price" onChange={(e) => handleFilter({ maxPrice: parseInt(e.target.value) })} />
<select onChange={(e) => handleFilter({ brand: e.target.value })}>
<option value="">All Brands</option>
<option value="Brand1">Brand1</option>
<option value="Brand2">Brand2</option>
</select>
{/* 商品列表展示 */}
{productList.map(product => (
<div key={product.id}>
<h3>{product.name}</h3>
<p>Price: {product.price}</p>
<p>Brand: {product.brand}</p>
</div>
))}
</div>
);
};
export default ProductList;
商品详情页
- 使用
useSelector
、useDispatch
和useEffect
:
import React, { useEffect } from'react';
import { useSelector, useDispatch } from'react-redux';
import { fetchProductDetail } from './actions';
const ProductDetail = ({ productId }) => {
const productDetail = useSelector(state => state.detailReducer.productDetail);
const loading = useSelector(state => state.detailReducer.loading);
const error = useSelector(state => state.detailReducer.error);
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchProductDetail(productId));
}, [dispatch, productId]);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
if (!productDetail) {
return null;
}
return (
<div>
<h2>{productDetail.name}</h2>
<p>Price: {productDetail.price}</p>
<p>Brand: {productDetail.brand}</p>
{/* 其他商品详情信息 */}
</div>
);
};
export default ProductDetail;
通过以上设计,利用 Redux 的 reducer 管理状态,action 触发状态变化,middleware 处理异步操作和缓存逻辑,再结合 React Hooks 方便地从 Redux store 中获取数据和分发 action,从而确保数据的一致性、高效性以及代码的可维护性。