Обновить данные / состояние конкретного компонента в React

У меня есть список продуктов-ID и кнопка. Когда я нажимаю кнопку, я хочу обновить данные в ListComponent. Я понятия не имею, как я могу сделать это в React. Кто-нибудь может мне помочь?

constructor(props) {
    super(props);
    this.state = {
      products: this.props.productData //where productData an array of all products-ID
    };
    this.refresh = this.refresh.bind(this);
 }  


  refresh() {
    this.setState({ products: null });
    this.forceUpdate();
  }

  render() {
    const { products } = this.state;
          <Button onClick={this.refresh} />
          <ListComponent
            data={products.map(entry => ({
              text: entry.productId
            }))}
          />
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  const products = selectAllProducts(state); //function that fetches-takes all products
  return {
    productData: products.map(products => ({
      productId: product.get("productId")
    }))
  };
};

2 ответа

Решение

Ваша функция обновления должна вызвать действие, которое извлекает данные и соответственно обновляет хранилище Redux. И поскольку вы сопоставили часть своего состояния Redux с реквизитами этого компонента, он будет повторно отображаться при извлечении и сохранении этих данных через редуктор.

Следовательно, вам вообще не нужно устанавливать локальное состояние в этом компоненте. Если у вас есть действие под названием fetchProductData:

class ProductList extends React.Component {
  constructor (props) {
    super(props)
    this.refresh = this.refresh.bind(this)
  }

  // if you don't already have the data in your store, you can fetch it here to kick things off
  componentDidMount () {
    this.props.fetchProductData()
  }

  refresh () {
    this.props.fetchProductData()
  }

  render () {
    const { products } = this.state
    return (
      <div>
        <Button onClick={this.refresh} />
        <ListComponent
          data={products.map(entry => ({
            text: entry.productId
          }))}
        />
      </div>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  const products = selectAllProducts(state)
  return {
    productData: products.map(products => ({
      productId: product.get("productId")
    }))
  }
}

export default connect(mapStateToProps, { fetchProductData })(MyComponent)

Опять же, это предполагает, что fetchProductData отправляет действие, которое обновит состояние редукции, где хранятся продукты. Передача действия connect как это сделает его доступным в качестве компонента в компоненте.

Похоже, вы разместили свой refresh() внутри конструктора попробуйте:

constructor(props) {
    super(props);
    this.state = {
      products: this.props.productData //where productData an array of all products-ID
    };
    this.refresh = this.refresh.bind(this);
}

refresh() {
  this.setState({ products: null });
  this.forceUpdate();
}

render() {
  const { products } = this.state;
        <Button onClick={this.refresh} />
        <ListComponent
          data={products.map(entry => ({
            text: entry.productId
          }))}
        />
  );
}

Я сделал минимальный компонент, который делает то, что вы хотите, чтобы он делал. Вместо привязки в конструкторе я использую функцию жирной стрелки для обновления.

import { Component } from "react";

const ListItem = props => props.item.text;

class List extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [{ id: 0, text: "zero" }, { id: 1, text: "one" }]
    };
  }

  refresh = () => {
    this.setState({ items: [] });
  };

  render() {
    const { items } = this.state;
    return (
      <div>
        {items.map(i => (
          <div key={i.id}>
            <ListItem item={i} />
          </div>
        ))}
        <button onClick={this.refresh}>refresh</button>
      </div>
    );
  }
}

export default List;

Вам не нужно forceUpdate(), компонент будет повторно визуализирован по умолчанию при смене реквизита.

Для объяснения жирной стрелы и что она делает для thisПроверьте https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4.

Другие вопросы по тегам