redux 另一个React Hook问题-无法读取未定义的属性(阅读'params')

bd1hkmkf  于 2022-11-12  发布在  React
关注(0)|答案(1)|浏览(118)

我似乎真的在react和hooks上遇到了麻烦。我知道这个问题可能是react-dom的问题。我正在看一个教程,它用5来做这个,而我用的是6。我看了文档,但老实说我找不到问题所在。它在我的主页上工作,但是现在产品页面不工作了,老实说,我在过去的答案中找不到任何关于这个问题的答案。有人有什么想法吗?谢谢!

import React, {useState, useEffect} from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Image, ListGroup, Button, Card } from 'react-bootstrap'
import Rating from '../components/Rating'
import Loader from '../components/Loader'
import Message from '../components/Message'
import { useParams } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { listProductDetails } from '../actions/productActions'

function ProductScreen({match}) {

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

    useEffect(() =>{
        dispatch(listProductDetails(match.params.id))

    },[])

ProductActions.js:

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

        const { id } = useParams();

        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, 
        })
    }
}

productReducer.js:

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
    }
}

store.js:

import { legacy_createStore as createStore, combineReducers, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
import {productListReducer,productDetailsReducer} from './reducers/productReducers'

const reducer = combineReducers({
    productList: productListReducer,
    productDetails: productDetailsReducer,
})
const initialState = {}
const middleware = [thunk]
const store = createStore(reducer, initialState, 
    composeWithDevTools(applyMiddleware(...middleware)))

export default store
llycmphe

llycmphe1#

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

        const { id } = useParams();
[...]

您正在将id作为listProductDetails的参数传递,然后在函数内部重新定义它。请将const { id } = useParams();移动到ProductScreen中,并将其作为参数传递给函数,而不要使用match
同样,listProductDetails返回一个异步函数,该函数以dispatch为参数,所以不要调用dispatch(listProductDetails(id)),而要调用listProductDetails(id)(dispatch)
在api中调用dispatch也不是一个好主意。你通常希望action函数返回要在React组件中调度的内容。

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

  useEffect(() => {
    const fetchData = async (id) => {
      dispatch({ type: PRODUCT_DETAILS_REQUEST });
      dispatch(await listProductDetails(id));
    };

    fetchData(id);
  }, [dispatch, id]);
  return <div>APP</div>;
}

在产品动作. js中

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

相关问题