React Context 在 Consumer 中没有显示价值

React Context doesn't show value in Consumer

我试图将值从上下文提供者传递给消费者,但它什么也没显示。

我在 Whosebug 上看过很多关于 React Context 不工作的问题,但我没有找到任何可以帮助我的问题。我在 Provider 中使用 Consumer,我试图将 Provider 包装在 div 中(它帮助了某人,但对我没有帮助),ContextTypes 不是这种情况,因为它是遗留文档,没有关于错误导入导出的错误,没有拼写检查错误,没有关于上下文或被动影响上下文的控制台错误。我做了上下文教程视频中的所有内容,以适应我的项目。

我在data.js中有一个'productTemplate'需要通过:

export const productTemplate = [
  {
    id: 1,
    title: "Samsung Galaxy S10",
    company: "Samsung",
    description: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium harum ipsam maiores excepturi, enim quae ex consectetur magnam quo temporibus error, vel iure eveniet id quas expedita cum cupiditate autem!",
    imageSrc: "samsung-galaxy-s10-1.webp",
    imageWidth: 200,
    imageHeight: 200,
    price: 300,
    isInCart: false,
    amountInCart: 0
  }
];

我有单独的上下文文件 - context.js:

import React, { Component } from 'react';
import { products, productTemplate } from './data'; // <-- imported 'productTemplate' correctly

const Context = React.createContext();

class ContextProvider extends Component {
  constructor() {
    super();
    this.state = {
      products: [],
      productTemplate: productTemplate  // <-- I need to pass it
    };

    this.setProducts = this.setProducts.bind(this);
    this.getItem = this.getItem.bind(this);
    this.onDetail = this.onDetail.bind(this);
  }

  // Don't mind next 4 methods, they're not related to 'productTemplate'

  componentDidMount() {
    this.setProducts();
  }

  setProducts() {
    let tempProducts = JSON.parse(JSON.stringify(products));
    this.setState(() => {
      return {products: tempProducts}
    })
  }

  getItem(id) {
    const product = this.state.products.find(item => item.id === id);
    return product;
  }

  onDetail(id) {
    const product = this.getItem();
    this.setState(() => {
      return { detailProduct: product }
    });
  }

  render() {
    return (
      <Context.Provider value={{ 
        ...this.state,                 // <-- passed this.state in value
        setProducts: this.setProducts,
        getItem: this.getItem,
        onDetail: this.onDetail
      }}>
        {this.props.children}
      </Context.Provider>
    )
  }
}

const ContextConsumer = Context.Consumer;

export { ContextProvider, ContextConsumer };
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

整个App被Provider包裹在index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ContextProvider } from './components/context';
import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.render(
  <ContextProvider>
    <Router>
      <App />
    </Router>
  </ContextProvider>, 
  document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

ProductPage.js 中,我正在 'title' 属性 上测试上下文,但它没有显示任何内容:

import React, { Component } from 'react';
import { StyledDivProductPage, StyledNavBreadcrumbs } from '../styles';
import { Link } from "react-router-dom";
import {  ContextConsumer } from '../context';

export default class ProductPage extends Component {
  render() {
    return (
      <ContextConsumer>
        {value => {
          const { id, title, company, description, imageSrc, price, isInCart, amountInCart } = value.productTemplate;
        
          return (
            <StyledDivProductPage>
              <StyledNavBreadcrumbs aria-label="breadcrumb" className="align-self-start">
                <ol className="breadcrumb">
                  <li className="breadcrumb-item"><Link to="/">Home</Link></li>
                  <li className="breadcrumb-item"><Link to="/mobile_phones">Mobile Phones</Link></li>
                  <li className="breadcrumb-item active" aria-current="page">{title}</li> {/*<-- here should be title value, but it shows nothing */}
                </ol>
              </StyledNavBreadcrumbs>
            </StyledDivProductPage>
          )
        }}
      </ContextConsumer>
    )
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

result

markup in DevTools

我明白了,这可能是一个幼稚的错误,但这只是我在 React 上的第二个项目。请帮帮我。

问题是 productTemplate 是一个值数组(不是对象)。将来,在调试时,我会建议从上下文中记录整个 value(而不是立即使用它)。例如,在 ProductPage 中的 return <StyledDivProductPage ... 之前添加一个 console.log(value).

这样做表明 productTemplate 是一个数组,因此访问 productTemplate.title 将是 undefined(这就是什么都没有呈现的原因)。

这可以通过访问第一项来解决:

const { id, title, ... } = value.productTemplate[0]; // access the first element

或者更新state中的初始值,例如:

const productTemplate = { ... } // instead of [{ ... }]