【问题标题】:ReactJS: Contents of a component not updating when a function inside render() is calledReactJS:调用render()中的函数时组件的内容不更新
【发布时间】:2020-12-27 22:29:11
【问题描述】:

我正在努力实现某些目标,但我不确定这是不是最好的方法:

我有一个显示在<ProductDisplay /> 组件内的产品数组(productArray)。我还有一个<FilterPanel />,它允许我对productArray 中的元素进行排序。 <ProductDisplay /><FilterPanel /> 都包含在名为 <MainContainer /> 的 hoc 中,格式如下:

<MainContainer>
    <FilterPanel />
    <ProductDisplay />
</MainContainer>

&lt;MainContainer /&gt; 在它的 render() 方法中有一个排序函数。排序函数被传递给&lt;FilterPanel /&gt;,当被调用时,它对productArray 进行排序。排序好的productArray从&lt;MainContainer /&gt;传递到&lt;ProductDisplay /&gt;

这里是&lt;MainContainer /&gt;的简化代码:

//import sorting functions: categorySort, timeSort, and ratingSort

class MainContainer extends Component {

  constructor(props) {
    super(props)

    this.state = {
      sort: ""
    }
  }

  render() {
    const { productArray } = this.props; //getting an array of products from props

    let sortResult = productArray; //if no sorting selected, sortResult will be the default order
  
    const performSort = (sortType) => {
      this.setState({sort: `${sortType}`}); //not really important

      switch(sortType) {
        case 'time':
          sortResult = timeSort(productArray); //gets sorted when called
          break;
        case 'category':
          sortResult = categorySort(productArray); //gets sorted when called
          break;
        case 'rating':
          sortResult = ratingSort(productArray); //gets sorted when called
        break;
        default:
          console.log('default case')
      }
    }

    console.log( `sortResult final`);
    console.log(sortResult);        //does not reflect sorting done above; still in initial state

    return (
      <div>
          <FilterPanel performSort={performSort}/>
          <ProductDisplay sortResult = {sortResult} />
      </div>
    );
  }
}

当从&lt;FilterPanel /&gt; 调用排序函数 'performSort' 时,它成功地在 switch 语句中生成了一个排序的 'sortResult' 数组,但是,switch 语句之外(之后)的 'sortResult' 没有改变(并且正在传递给&lt;ProductDisplay /&gt; 不变)。这很奇怪,因为 'sortResult' 应该在 switch 语句的范围内。

非常感谢任何帮助解决这个问题(此外,任何关于如何做得更好的建议。请注意,我还没有学习钩子,所以我更喜欢没有钩子的解决方案)。

【问题讨论】:

  • 我相信为了重新渲染数据,您需要setState。为什么不将sortResult 添加到您的state 对象中,并在switchsetState({sortResult}) 之后?另外,你的render 方法为什么有这么多逻辑而不是render() 之外的逻辑?
  • 我实际上把它放在了render里面,这样它就可以修改最初在那里初始化的'sortResult'。我想我现在明白了,除非我将“sortResult”放在状态中,否则它不会修改它,所以我将把函数移到 render() 之外

标签: javascript reactjs scope


【解决方案1】:

React 组件仅在传入的 props 更改、状态更改或使用的上下文更改时重新渲染。 (或者,在 React Router 中,当 URL 发生变化时。)这个基本事实是理解 React 的关键部分。

在这种情况下,您正在更改 Javascript 变量......但不是我提到的三(四)件事之一。

要解决此问题,您可以将sortResult 设为您的状态的一部分(即this.state.sortResult),然后在完成排序后将setState 设为它。因为那改变状态,它会导致你的组件重新渲染,并从你返回的 JSX 生成新的 DOM。

【讨论】:

  • 谢谢!我之前认为问题可能与重新渲染有关,但后来认为无论哪种方式, sortResult 仍然需要在开关之外进行修改(这是一个单独的问题)。我现在意识到只有 performSort 函数中的内容会被更改,但组件不会注意到任何内容被更改,因为它没有重新渲染 - 因此位于 performSort 函数之外的 sortResult 数组将保持不变。我想我是在自言自语——谢谢你的解释!
猜你喜欢
  • 2019-02-01
  • 2016-09-08
  • 1970-01-01
  • 2020-12-17
  • 2015-07-11
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2016-10-23
相关资源
最近更新 更多