Как передать массив с данными от одного компонента к другому?

Чтобы лучше объяснить, в какой иерархии расположены компоненты, я прибегну к paint c:
5a3abb99d31ff664714367.png
Итак, нужно при клике по кнопке "подробнее" в Item.jsx передать массив с id, ценой и описанием(descr) в More.jsx.

Source
Items.jsx
import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Item from '../components/Item';
import Cart from '../components/Cart';

import '../css/shop.css';
import '../css/keyload.css';

export default class Items extends Component{
    constructor(props){
        super();
        this.state ={
          items: [],
          itemId: 0
        };
        this.handleCartPriceChange = this.handleCartPriceChange.bind(this);
        this.handleDelete = this.handleDelete.bind(this);
      }
      componentDidMount(){
        
      }
      handleDelete(i){ // вызывается при нажатии на корзину в Cart.jsx    
      // создадим новый массив, что бы не мутировать предыдущий, 
      // после чего методом splice удалим элемент и запишем в state
        const newItems = [...this.state.items];
        newItems.splice(i, 1);
        this.setState({items: newItems})
      }
      handleCartPriceChange(item){  // вызывается для передачи данных об объекте из Item.jsx в Cart.jsx при клике на кнопку в Item.jsx
        this.setState({ items: [...this.state.items, item]});
      }
      render(){
        return(
          <div className="wrap">
            <Cart onDelete={this.handleDelete} items={this.state.items} />
            <section className="shop">
              <div className="wrap_container">
              {this.props.items.map(item =>
                <Item key={item.id} title={item.title} price={item.price} onCartPriceChange={this.handleCartPriceChange} shirt ={item.img}/>
              )}</div>
            </section>
          </div>
        );
      }
    }
    Items.propTypes = {
      items: PropTypes.array.isRequired // передача массива с объектами
    };


Item.jsx
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {Link} from 'react-router-dom';

import Button from './Button';

export default class Item extends Component{
    constructor(props){
        super(props);
        this.state={
          btn_children: 'ADD'
        };
        this.onCartPriceChange = this.onCartPriceChange.bind(this);
        this.onCartPriceOver = this.onCartPriceOver.bind(this);
      }
      onCartPriceChange(){ // срабатывает при наведении курсора на кнопку
        this.setState({ btn_children: this.props.price + '$',})
      }
      onCartPriceOver(){ // срабатывает при уберании курсора с кнопки
        this.setState({btn_children: 'ADD'})
      }
      render(){
        return(
          <div className="shop__item">
            <img className="item" src={this.props.shirt} alt=""/>
            <div className="title">
              <Link to="more" className="descr">подробнее</Link>
              <Button onMouseOver={this.onCartPriceChange} onMouseOut={this.onCartPriceOver} onClick={()=> this.props.onCartPriceChange({price: this.props.price, title: this.props.title})} className="btn_buy">{this.state.btn_children}</Button>
            </div>
          </div>        
        );
      }
    }
    Item.propTypes = {
      title: PropTypes.string.isRequired, // используется для передачи названия объектов, переданных в Cart.jsx
      price: PropTypes.number.isRequired, // используется для передачи цены объектов, переданных в Cart.jsx
      onCartPriceChange: PropTypes.func.isRequired, // передаёт функцию, предназначенную для передачи данных объекта при клике на него 
      shirt: PropTypes.string // картинка товара
    };


App.jsx
import React, {Component} from 'react';
import {Route} from 'react-router-dom';

import items from './item_db';

import Nav from './components/Nav';
import Footer from './components/Footer';

import Home from './pages/Home';
import About from './pages/About';
import Items from './pages/Items';
import More from './pages/More';

class App extends Component{
    constructor(props){
        super(props);
        this.state ={
            itemId : []
        };
    }
    handleItemIdReceiver(){
        this.setState({itemId: []})
    }
    render(){
        return (
            <main>
                <Nav/>
                    <div className="content">
                    <Route exact path="/" component={Home} />
                    <Route exact path="/about" component={About}/>
                    <Route exact path="/shop" render={()=> <Items items={items} />}/>
                    <Route path="/more" render={()=><More items={items}/> }/>
                    <Footer/>
                </div>
            </main>
        );
    }
}
export default App;


More.jsx
import React from 'react';
import {Link} from 'react-router-dom';

import '../css/more.css';

export default function More(props){
    var items = props.items;
    var title= items.reduce((p, items) => items.title);
    var itemImage = items.reduce((p,items)=> items.img);
    var descr = items.reduce((p, items) => items.descr);
    console.log(items);
    return(
        <div className="more__info">
            <img src={itemImage} alt=""/>
            <div className="title"> 
                <h1 className="title__name">{title}</h1>
                <p className="descr">
                {
                    descr
                }            
                </p>
                <div className="wrap">
                    <Link to="/shop" className="back">Назад</Link>
                </div>
            </div>
        </div>
    );
}
  • Вопрос задан
  • 2252 просмотра
Решения вопроса 2
rockon404
@rockon404 Куратор тега React
Frontend Developer
По-хорошему redux.
Но вы так же можете передавать список из App в Items с колбек функцией, которая запишет в state компонента App id выбранного продукта, ее надо прокинуть через Items в каждый Item и там по клику вызывать:
class App extends Component {
  state = {
    activeItemId: -1,
  };
  
  selectItem = id => {
    this.setState({
       activeItemId: id,
    });
  };

  render() {
    const { items } = this.props;
    const { activeItemId } = this.state;
   
    const activeItem = items.find(item => item.id === selectedItemId);

    return (
      <Wrapper>
        <More item={activeItem} />
        <Items 
          items={items}
          onSelectItemCalback={this.selectItem}
        />
      </Wrapper>
    );
  }
}
Ответ написан
Комментировать
RomReed
@RomReed
JavaScript, Flutter, ReactNative, Redux, Firebase
Вам нужно использовать redux
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
27 апр. 2024, в 18:49
5000 руб./за проект
27 апр. 2024, в 18:43
5000 руб./за проект
27 апр. 2024, в 18:42
1500 руб./за проект