【问题标题】:Refresh a specific component 's data/ state in React在 React 中刷新特定组件的数据/状态
【发布时间】:2018-12-05 09:13:38
【问题描述】:

我有一个产品 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")
    }))
  };
};

【问题讨论】:

  • 如果您的 render 方法依赖于 state 或 props 以外的数据,您只应该使用 forceUpdate。在你的情况下它是没用的。
  • 通过“刷新数据”您是否打算将产品属性设置为null?还是有来自其他地方的新数据?
  • @hindmost 好的!你能给我一个提示,我不知道如何刷新 ListComponent 的数据?
  • 我将如何刷新 ListComponent 的数据.. 这取决于你的数据究竟来自哪里。
  • @djfdev 没有。我不想将产品属性设置为空。我真正想做的是刷新,因为可能会从其他地方添加一些新产品。我想将状态设置为 null 然后显示新状态,但这不是一个好方法。你知道我将如何刷新数据吗?

标签: javascript reactjs react-component


【解决方案1】:

您的刷新函数需要调用一个获取数据的操作,并相应地更新 Redux 存储。而且因为你已经将部分 Redux 状态映射到了这个组件的 props,所以当通过 reducer 获取和保存数据时它会重新渲染。

因此,您根本不需要在此组件中设置本地状态。如果您有一个名为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 调度了一个操作,该操作将更新存储产品的redux 状态。像这样将操作传递给connect 将使其作为组件内的道具可用。

【讨论】:

    【解决方案2】:

    看起来您已将 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(),组件在props改变时默认会重新渲染。

    有关粗箭头的说明及其对this 的作用,请查看https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

    【讨论】:

    • 这不是问题所在。那是我的复制粘贴错误。 this.forceUpdate() 不起作用。
    • 我用一个可以满足您要求的最小组件更新了我的答案。 @凯瑟琳汉森
    猜你喜欢
    • 1970-01-01
    • 2018-09-25
    • 2018-08-06
    • 2020-05-26
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    相关资源
    最近更新 更多