Задать вопрос

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

Чтобы лучше объяснить, в какой иерархии расположены компоненты, я прибегну к 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>
    );
}
  • Вопрос задан
  • 2312 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 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
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы