重新加载页面时无法读取未定义的 属性 'ArtisanID'

Cannot read property 'ArtisanID' of undefined when I reload the page

当我重新加载页面时,我得到这个 error:Cannot read 属性 'ArtisanID' of undefined.

如何解决这个问题?

我是这个框架的新手,认为可能是因为刷新页面时组件指令没有呈现。

我正在使用 3 个上下文,所以我不能使用 React.Component 类,除非我将所有 3 个结合起来,但我认为这不是一个好主意。

import React, { useContext } from 'react'
import { Link } from 'react-router-dom'
import { ProductContext } from '../../global/ProductContext'
import { ArtisanContext } from '../../global/ArtisanContext'
import ProductCard from './ProductCard'
import { CartContext } from '../../global/CartContext'

const ProductPage = (props) => {

    //props.preventDefault();

    const {products} = useContext(ProductContext)
    const {artisans} = useContext(ArtisanContext)
    const { dispatch } = useContext(CartContext);

    let productIDFind = props.match.params.id

    const product = products.find(x=> x.ProductID === productIDFind)
    const artisan = artisans.find(x=> x.ArtisanName === product.ProductArtisan)

    const otherProducts = []

    products.forEach(product => {
        if (artisan.ArtisanName === product.ProductArtisan) {
            otherProducts.push(<ProductCard key={product.ProductID} product={product} />)
        }
    });

    return (
        <section className="productPage main-section">
            <div className="productPage-container main-section-constainer">
                <Link className="artisanLink" to={'/Artisans/' + artisan.ArtisanID}>
                    <h1>Par <span>{artisan.ArtisanName}</span></h1>
                </Link>
                <div className="row">
                    <div className="productPage-principaleImg bg-img" style={{ backgroundImage: `url(${product.ProductProfilePicture})` }}></div>
                    <div className="productPage-info col">

                            <div className="row">

                                <div className="col">
                                    <h2 className="productPage-Name">{product.ProductName}</h2>
                                    <p className="productPage-Description">{product.ProductDescription}</p>
                                </div>

                                <div className="row">
                                    <div className="productPage-Price">{product.ProductPrice}€</div>
                                    <button className="addBtn" onClick={(e) => {
                                        e.preventDefault();
                                        dispatch({ type: 'ADD_TO_CART', id: product.ProductID, product })}}>
                                        <span>Ajouter</span>
                                        <span className="addImg bg-img"></span>
                                    </button>
                                </div>

                            </div>

                            <div className="productPage-moreImg row">
                                <a className="productPage-YT-link" rel="noreferrer" href={product.ProductYT} target="_blank">
                                    <div className="productPage-YT bg-img" style={{ backgroundImage: `url(${product.ProductProfilePicture})` }}></div>
                                    <div className="productPage-YT-img bg img"></div>
                                </a>
                                <div className="productPage-img bg-img" style={{ backgroundImage: `url(${product.ProductSecondImg})` }}></div>
                                <div className="productPage-img bg-img" style={{ backgroundImage: `url(${product.ProductTreeImg})` }}></div>
                            </div>

                        </div>
                    </div>
                <h3>Autre produits de {artisan.ArtisanName}</h3>
                <div className="otherProducts">
                    {otherProducts}
                </div>
            </div>
        </section>
    )
}

export default ProductPage

ArtisanContext

import React, { createContext } from 'react'
import { db } from '../data/firebase'

export const ArtisanContext = createContext();

export class ArtisanContextProvider extends React.Component{

    // Définition du state initial avec un tableau vide
    state = {
        artisans:[]
    }

    componentDidMount(){

        const prevArtisans = this.state.artisans;
        db.collection('Artisans').onSnapshot(snapshot => {
            let changes = snapshot.docChanges();
            changes.forEach(change => {
                if (change.type === 'added') {
                    prevArtisans.push({
                        ArtisanID: change.doc.id,
                        ArtisanName: change.doc.data().ArtisanName,
                        ArtisanNbrProduits: change.doc.data().ArtisanNbrProduits,
                        ArtisanCategorie: change.doc.data().ArtisanCategorie,
                        ArtisanDescription: change.doc.data().ArtisanDescription,
                        ArtisanProfilePicture: change.doc.data().ArtisanProfilePicture,
                        ArtisanBanner: change.doc.data().ArtisanBanner
                    })
                }
                this.setState({
                    artisans: prevArtisans
                })
            }) 
        })
    }

    render() {
        return (
            <ArtisanContext.Provider value={{artisans:[...this.state.artisans]}} >
                {this.props.children}
            </ArtisanContext.Provider>
        )
    }
}

我看到 artisan 是由 artisans.find 声明的。如果没有找到项目,artisans.find 的结果可能是 undefined。所以会出现这个问题。为避免此问题,您可以使用 optional chaining:

<Link className="artisanLink" to={'/Artisans/' + artisan?.ArtisanID}>
   <h1>Par <span>{artisan?.ArtisanName}</span></h1>