【问题标题】:React Context doesn't show value in ConsumerReact Context 在消费者中没有显示价值
【发布时间】:2020-01-29 19:10:48
【问题描述】:

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

我在 StackOverflow 上看过很多关于 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被包裹在index.js中的Provider中:

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 上的第二个项目。请帮帮我。

【问题讨论】:

    标签: reactjs react-context


    【解决方案1】:

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

    这样做表明productTemplate 是一个数组,因此访问productTemplate.title 将是undefined(这就是为什么什么都不渲染的原因)。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      相关资源
      最近更新 更多