首页 > 解决方案 > 从子组件中的事件触发状态更改

问题描述

我正在 React 中构建一个基本的购物篮,但我有点卡住了。

因此,App 拥有整个 JSON 数据(只是从本地文件中提取的),我设想 Cart 将维护购物车的状态 - 可能是一组产品 ID。它还将用于使用路线 /cart 显示购物车的内容。

好的,所以问题的症结在于我有 ClothingList 组件,它通过将“ClothingItem”组件推送到数组来构建项目。在这个组件 (ClothingItem) 中,是无处不在的产品展示和“添加到购物车”按钮:

<div className="items__item">
 <h3>{props.item.name} - {props.item.brand}</h3>
 <div className="item__price">
    &pound;{props.item.price}
 </div>
 <div className="item__photo">
   <img src={process.env.PUBLIC_URL + '/product-imgs/' + props.item.photo} alt="" />
 </div>
 <div className="item__buttons">
   <button>Add to cart</button>
 </div>
</div>

现在,我需要通过传递产品 ID 来调用函数/实例化购物车的按钮。但是如何创建这个数据流呢?请注意,Cart 没有以任何方式连接到 ClothingItem,因此回调函数不会起到太大作用。

实际上,我需要购物车的状态可以全局访问(如果这意味着将其放入 App 中,那就这样吧)。

非常感谢任何帮助。我从代码片段中省略了购物车和其他一些内容,因为它们要么不完整,要么对问题不重要。


应用程序:

import React, { Component } from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import './main.css'
import './font-awesome.css'
import Header from './components/Header'
import ClothingList from './components/ClothingList'
import Home from './components/Home'
import Footer from './components/Footer'
import Cart from './components/Cart'
import clothesData from './components/json/clothes.data.json'

class App extends Component {

  componentDidMount() {
    this.setState({
      clothesData: clothesData
    })
  }

  render = () => {
    return (
      <Router>
        <div className="App">
          <div className="wrapper"> 
            <Header />
            <main>
              <Route exact path="/" 
                render={() => <Home clothesData={clothesData} />}
              />
              <Route 
                path="/clothes/:item" 
                render={props => <ClothingList {...props} clothesData={clothesData} />}
              />
              <Route 
                path="/cart" 
                component={Cart} 
              />
            </main>
          </div>
          <Footer />
        </div>
      </Router>
    )
  }
}

export default App;


服装清单:

import React from 'react'
import ClothingItem from './ClothingItem'
import ClothingNav from './ClothingNav'

const ClothingList = props => {
  const getQuery = () => {
    let queryJSON
    let displayItems

    if ( props.displayItems ){
      displayItems = props.displayItems
    } else {
      displayItems = props.match.params.item   
    }

    switch ( displayItems ) {
      case 'tshirts':
        queryJSON = props.clothesData.tshirts
        break
      case 'jumpers':
        queryJSON = props.clothesData.jumpers
        break
      case 'trousers':
        queryJSON = props.clothesData.trousers
        break
      case 'jackets':
        queryJSON = props.clothesData.jackets
        break
      case 'suits':
        queryJSON = props.clothesData.suits
        break
      default: 
        queryJSON = props.clothesData.tshirts
        break
    }

    return queryJSON
  }

  const getItems = () => {
    let items = []
    let queryJSON = getQuery()

    for ( let i = 0; i < queryJSON.length; i++ ) {
      items.push(
        <ClothingItem 
          key={i} 
          item={queryJSON[i]}
        />
      )
    }
    return items
  }

  return (
    <div>
      <div className="grid-container">
        <ClothingNav />
        <div className="heading">
          <h2>{props.displayItems}</h2>
        </div>
        <div className="items">
          {getItems()}
        </div>
      </div>
    </div>
  )
}

export default ClothingList

服装项目:

import React from 'react'

const ClothingItem = props => {
  return (
    <div className="items__item">
      <h3>{props.item.name} - {props.item.brand}</h3>
      <div className="item__price">
        &pound;{props.item.price}
      </div>
      <div className="item__photo">
        <img src={process.env.PUBLIC_URL + '/product-imgs/' + props.item.photo} alt="" />
      </div>
      <div className="item__buttons">
        <button>Add to cart</button>
      </div>
    </div>
  )
}

export default ClothingItem

标签: reactjs

解决方案


您可以创建函数来更改父组件中的状态并将其作为道具传递给子组件。


推荐阅读