Передача props между компонентами в React

171
12 февраля 2019, 02:20

У меня есть несколько компонентов по сути никак не связанных между собой, первый это ShoppingCards

import { sample } from 'rxjs/internal/operators'; 
import React from 'react'; 
import ShoppingCard from './ShoppingCard'; 
import goods from './goods.json'; 
 
export default class ShoppingCards extends React.Component { 
    constructor (props){ 
        super(props); 
        this.shoppingCardsJSX = goods.map((good) => { 
            return ( 
                <ShoppingCard 
                    key = {good.id } 
                    goodId = {good.id} 
                    src = {good.src} 
                    descr = {good.descr} 
                    code = {good.code} 
                    size = {good.size} 
                    color = {good.color} 
                    price = {good.price} 
                    onRemoveCard={this.removeCard.bind(this) 
                    } 
                /> 
            ); 
        }); 
    } 
    removeCard(obj){ 
        const list = this.shoppingCardsJSX ; 
        for (let i = 0; i < list.length; i++){ 
            if (list[i].key === obj){                 
                list.splice(i, 1); 
                break; 
            } 
        } 
        this.forceUpdate();      
    } 
    render() { 
        return this.shoppingCardsJSX; 
    } 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Второй это SearchBlock.js:

import React from 'react'; 
import main_logo from '../images/logo-main.png'; 
import ShoppingCard from './ShoppingCard' 
 
class SeekBlock extends React.Component { 
    render() { 
        return ( 
            <label htmlFor={this.props.id}> 
                <input type = "text" placeholder="Поиск по сайту" className={this.props.className} id = {this.props.id}/> 
            </label> 
        ) 
    } 
} 
export default class SearchBlock extends React.Component { 
    constructor(props) { 
        super(props); 
        this.spanObject = { userName: 'Анастасия'}; 
    } 
    render() { 
        return ( 
           <div className="search-block"> 
             <img className="main-logo" src = {main_logo} alt ={this.props.className}/> 
             <div className="seek-block"> 
                <SeekBlock className="search-string" id = "search"/> 
             </div> 
             <div className="account-block"> 
                 <div className="user-info user-info--name"> 
                    <a className="user-info__user-name" href="/">{this.spanObject.userName}</a> 
                 </div> 
                 <div className="user-info user-info--user-bucket"> 
                     <a className="user-info__bucket" href="/" >В корзине: 4 <br/> товара</a> 
                 </div> 
             </div> 
           </div> 
        ); 
    } 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Проблема в том, что мне нужно, чтобы длина массива this.shoppingCardsJSX.length из ShoppingCards как-то попала в SearchBlock, что-то вроде:

<a className="user-info__bucket" href="/" >В корзине: {this.shoppingCardsJSX.length} <br/> товара</a>

и каждый раз обновлялась в зависимости от длинны массива.

Компонент ShoppingCards импортится в компонент ShoppingList, ShoppingList импортится в MainContent, а MainContent импортится в ShopPage. Компонент SearchBlock сразу импортится в ShopPage.

Никак не могу с этим разобраться, помогите пожалуйста. Прочитала похожие решения на стеке, но ни одно из них не получилось реализовать. Возможно ли это вообще сделать без redux?

Answer 1

сделайте родительский компонент который будет получать goods.json и хранить у себя в state

class Parent extends React.Component{
  constructor() {
    super()
    this.state = { goods: JSON.parse(goods.json) }
  }
  render() {
    return(
      <React.Fragment>
        <ShoppingCards goods={this.state.goods} />
        <SearchBlock goodsLength={this.state.goods.length} />
      <React.Fragment>
    )
  }
}

Это не самый оптимальный вариант но он вполне подходит... а вообще поставьте себе mobx и у вас будет доступ к состоянию в любой точке приложения

READ ALSO
Не работает onYouTubeIframeAPIReady

Не работает onYouTubeIframeAPIReady

При успешной загрузке Ajax функция onYouTubeIframeAPIReady ни в какую не хочет работатьЕсть подозрение, что функция эта вызывается только один раз

164
Замена строк регулярным выражением в JS

Замена строк регулярным выражением в JS

Есть строка: СЧЁТЕСЛИМН('ИСХ_Сделки'!$B:$B;C$3;'ИСХ_Сделки'!$J:$J;$A18)СУММ(C18:I18)AK18+AT18+AB18+S18+J18СУММ(U18:AA18) На выходе нужно получить: СЧЁТЕСЛИМН('ИСХ_Сделки'!$B:$B;C$3;'ИСХ_Сделки'!$J:$J;$A18)СУММ(C122:I122)AK122+AT122+AB122+S122+J122СУММ(U122:AA122)

262
Релизация flatMap JavaScript

Релизация flatMap JavaScript

При добавлении к конструктору Array свойства flatMap нужно задать определенный контекстКак это лучше сделать?

197