另一个 React 钩子问题 - 无法读取未定义的属性(读取"参数")



我似乎真的在react和hook方面遇到了麻烦。我知道问题可能在于如何应对。我正在看一个教程,用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
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也不是一个好主意。您通常希望操作函数返回要在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>;
}

In-ProductActions.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,
};
}
};

相关内容

  • 没有找到相关文章