开发者问题收集

未捕获的类型错误:使用 Redux 和 react-router-dom 实现时无法读取未定义的属性(读取‘params’)[重复]

2022-08-28
1116

因此,我一直在关注 MERN 堆栈课程,但不知何故,他使用的 react-router-dom 版本已过时。我一直遇到此错误:

未捕获的 TypeError:无法读取未定义的属性(读取“params”)

我尝试更改代码以使其与更新的版本保持一致,例如使用 useParams();但我认为我错误地实现了代码。

这是当前使用 react-router-dom v6.3 的 ProductScreen.js 组件的原始代码:

const ProductScreen = ({match}) => {
 

  const dispatch = useDispatch();
  
  const productDetails = useSelector(state => state.productDetails);
  const {loading, error, product} = productDetails;

  useEffect (() => {
    dispatch(listProductDetails(match.params.id));
  },[dispatch, match]);
      return(//code here)

这是 productActions.js 文件:

export const listProducts = () => async (dispatch) =>{
    try{
        dispatch({ type: PRODUCT_LIST_REQUEST});

        const {data} = await axios.get('api/products');
        dispatch({
            type: PRODUCT_LIST_SUCCESS,
            payload: data
        })
    }catch(error){
        dispatch({
            type: PRODUCT_LIST_FAIL,
            payload: error.response && error.response.data.message ? error.response.data.message : error.message,
        })
    }
}
export const listProductDetails = (id) => async (dispatch) =>{
    try{
        dispatch({ type: PRODUCT_DETAILS_REQUEST});

        const {data} = await axios.get(`api/products/${id}`);
        
        dispatch({
            type: PRODUCT_DETAILS_SUCCESS,
            payload: data,
            
        })
        
    }catch(error){
        dispatch({
            type: PRODUCT_DETAILS_FAIL,
            payload: error.response && error.response.data.message ? error.response.data.message : error.message,
        })
    }
}

这是我的 Product.js 文件:

const Product = ({ product }) => {
  return (
    <div>
        <Card className='my-3 p-3 rounded'>
            <Link to={`/product/${product._id}`}>
                <Card.Img src={product.image} variant='top' />
            </Link>
            <Card.Body>
                <Link to={`/product/${product._id}`}>
                    <Card.Title as='div'><p>{product.name}</p></Card.Title>
                </Link>
                <Card.Text as='div'>
                    <Rating 
                    value={product.rating} 
                    text={`${product.numReviews} reviews`} />
                </Card.Text >
                <Card.Text as='h3'>
                    ₱{product.price}
                </Card.Text>
            </Card.Body>
        </Card>
    </div>
  )
}

这是我的 productReducers.js:

export const productListReducer = (state = { products: []}, action) => {
    switch(action.type){
        case PRODUCT_LIST_REQUEST:
            return{loading: true, products: []}
        case PRODUCT_LIST_SUCCESS:
            return {loading: false, products: action.payload}
        case PRODUCT_LIST_FAIL:
            return {loading: false, error: action.payload}
        default:
            return state
    }
}

export const productDetailsReducer = (state = { product: {reviews: []}}, action) => {
    switch(action.type){
        case PRODUCT_DETAILS_REQUEST:
            return{loading: true, ...state}
        case PRODUCT_DETAILS_SUCCESS:
            return {loading: false, product: action.payload}
        case PRODUCT_DETAILS_FAIL:
            return {loading: false, error: action.payload}
        default:
            return state
    }
}

非常感谢!

2个回答

问题最有可能出现在这里:

const ProductScreen = ({match}) => {

match 已被替换为 useMatch

尝试执行以下操作:

const ProductScreen = () => {
  const match = useMatch();
Konrad
2022-08-28

经过几个小时的反复试验,我终于解决了这个问题:

在 ProductScreen.js 中:

const ProductScreen = () => {
 

  const dispatch = useDispatch();
  const {id} = useParams();
  
  const productDetails = useSelector(state => state.productDetails);
  const {loading, error, product} = productDetails;

  useEffect (() => {
    dispatch(listProductDetails(id));
  },[dispatch, id]);
      return(//code here)

首先,删除所有与“match”相关的代码。将 match.params.id 替换为 id,然后通过 const {id} = useParams(); 创建 id 变量。还要确保已导入 useParams。

接下来在 productActions.js 文件中:

export const listProductDetails = (id) => async (dispatch) =>{
    try{
        dispatch({ type: PRODUCT_DETAILS_REQUEST});

        const {data} = await axios.get(`/api/products/${id}`);
        
        dispatch({
            type: PRODUCT_DETAILS_SUCCESS,
            payload: data,
            
        })
        
    }catch(error){
        dispatch({
            type: PRODUCT_DETAILS_FAIL,
            payload: error.response && error.response.data.message ? error.response.data.message : error.message,
        })
    }
}

不要忘记在 axios 请求中添加“/”: /api/products/${id

Jeheu Dela Cruz
2022-08-29