Как динамически изменить state в react js?

262
28 мая 2022, 22:50

У меня есть главный компонент App, в его state я передал массив объектов, а потом этот массив объектов передал через пропс в state второго компонента, где с помощью метода map я прошёлся по каждом элементы и отрисовал его. Каждый элемент это типо продукт, и каждого продукта есть кнопка. Вопрос в том, как сделать так, чтобы при клике на эту кнопку изменялся state только того продукта, на кнопку которого было нажатие. Буду благодарен за подсказку

Вот главный компонент App:

import React, { Component } from 'react';
import Header from './Components/Header/Header';
import Products from './Components/Products/Products';
class App extends Component{
  constructor(props) {
    super(props)
    this.state = {
      products: [
        {name: "Волшебный корабль", price: 300, id:1},
        {name: "Безумный корабль корабль", price: 320, id:2},
        {name: "Корабль судьбы", price: 350, id:3},
      ]
    }
  }
  render() {
    return (
      <div className="App">
        <Header />
        <Products products={this.state.products} />
      </div>
    );
  }
}
export default App;

А вот компонент, в который я передал массив объектов:

import React, { Component } from 'react';
class Products extends Component {
    constructor(props) {
        super(props)
        this.state = {
            products: props.products,
        }
        this.changeState = this.changeState.bind(this);
    }
    changeState() {
        this.setState(state => ({
            //Тут я так понял что-то нужно изменить 
        }))
    }
    render() {
        let productsArr = this.state.products;
        console.log(productsArr);
        return(
            <div className="Products">
                {productsArr.map(item => {
                    return(
                        <div key={item.id}>
                            <h1>{item.name}</h1>
                            <h2>{item.price}</h2>
                            <button onClick={() => this.changeState()}></button>
                        </div>
                    )
                })}
            </div>
        )
    
    }
}
export default Products;
Answer 1

Незачем свойства копировать внутрь компонента, можно прям в рендере использовать их и все автоматически перерисуется

Советую перечитать официальный туториал, там все эти моменты объяснены

import React, { Component } from 'react';
import Header from './Components/Header/Header';
import Products from './Components/Products/Products';
class App extends Component{
  constructor(props) {
    super(props)
    this.state = {
      products: [
        {name: "Волшебный корабль", price: 300, id:1},
        {name: "Безумный корабль корабль", price: 320, id:2},
        {name: "Корабль судьбы", price: 350, id:3},
      ],
      clickedProduct: null
    }
  }
  
  onProductClick=(item)=>{
    this.setState({
      clickedProduct: item
    })
  }
  
  render() {
    return (
      <div className="App">
        <Header />
        <Products products={this.state.products} onClick={this.onProductClick} />
      </div>
    );
  }
}
export default App;
<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>

import React, { Component } from 'react';
class Products extends Component {
    render() {
        const productsArr = this.props.products;
        return(
            <div className="Products">
                {productsArr.map(item => {
                    return(
                        <div key={item.id}>
                            <h1>{item.name}</h1>
                            <h2>{item.price}</h2>
                            <button onClick={()=> this.props.onClick(item)}></button>
                        </div>
                    )
                })}
            </div>
        )
    
    }
}
export default Products;
<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>

READ ALSO
Маска ввода из значений массива

Маска ввода из значений массива

Как можно реализовать маску ввода, критерием совпадения которой был бы инкрементируемый ряд либо значения из массива, например 100, 200, 300, 400

241
node.js discord.js В чем проблема?

node.js discord.js В чем проблема?

Cannot read property 'includes' of undefinedКод:

140
cors возвращает ошибку

cors возвращает ошибку

Я делаю fetch-запрос на свой сервер:

259