javascript - React 中的无限渲染

标签 javascript reactjs react-native

我无法弄清楚为什么我的应用程序会进行无休止的渲染。

在内部,我的有状态组件,我在 componentDidMount 方法中调用一个 redux Action (调用 componentWillMount 也做无尽的渲染)

class cryptoTicker extends PureComponent {
  componentDidMount() {
    this.props.fetchCoin()
    // This fetches some 1600 crypto coins data,Redux action link for the same in end
  }

  render() {
    return (
      <ScrollView>
        <Header />
        <View>
          <FlatList
            data={this.state.searchCoin ? this.displaySearchCrypto : this.props.cryptoLoaded}
            style={{ flex: 1 }}
            extraData={[this.displaySearchCrypto, this.props.cryptoLoaded]}
            keyExtractor={item => item.short}
            initialNumToRender={50}
            windowSize={21}
            removeClippedSubviews={true}
            renderItem={({ item, index }) => (
              <CoinCard
                key={item["short"]}
              />
            )} 
          />
        </View>
      </ScrollView>
    )
  }
}

在 CoinCard 中,除此之外我什么都不做(注意 Flat 列表中的 CoinCard)

class CoinCard extends Component {
  render () { 
    console.log("Inside rende here")
    return (
        <View> <Text> Text </Text>  </View>
    )  
  }
}

现在,当我控制台登录我的 coincard 渲染时,我可以看到 Inside rende here

的无限日志

[问题:]谁能帮我弄清楚为什么会发生这种情况?

您可以 click here to see my actionsclick here to see my reducer .

[更新:] 我的 repository is here如果您想克隆并自己查看。

[更新:2]:我已将上述共享代码推送到 github 上,它仍然会记录无穷无尽的 console.log 语句(如果你可以克隆,run and move back to this commit)。

[更新:3]:我不再使用 <ScrollView /><FlatList />当我指的是无休止的渲染时,我的意思是它是无休止的(并且不必要地)将相同的 Prop 传递给子组件(<Coincard />),如果我使用 PureComponent,它不会无休止地登录 render () {但在 componentWillRecieveProps , 如果我这样做 console.log(nextProps) , 我可以看到相同的日志一遍又一遍地传递

最佳答案

您的代码中有一些需要注意的地方。

  • CoinCard 组件必须是 PureComponent,如果 props 是 shallow-equal,则不会重新渲染。
  • 您不应该在 ScrollView 组件中渲染您的 Flatlist,这会使组件同时渲染其中的所有组件,这可能会导致 之间出现更多循环FlatlistScrollView
  • 您还可以为渲染的组件设置一个明确的高度,以减少为其他 Prop 渲染组件的次数。
  • 另一件需要注意的事情是,根据下面提到的日志语句,只有组件中的 props 会在滚动底部呈现

    import {Dimensions} from 'react-native'
    
    const {width, height} = Dimensions.get('window)
    
    class CoinCard extends React.PureComponent {
    render () { 
      console.log(this.props.item.long)  //... Check the prop changes here, pass the item prop in parent Flatlist. This logs component prop changes which will show that same items are not being re-rendered but new items are being called.
      return (
        <View style={{height / 10, width}}> //... Render 10 items on the screen
          <Text>
            Text
          </Text>
        </View>
      )  
     }
    }
    

更新

这个额外的日志记录是由于从 Flatlist 到您的组件的 props 没有 PureComponent 浅层比较

请注意,componentWillReceiveProps() 已弃用,您应该在代码中避免使用它们。 React.PureComponent 在幕后工作并使用 shouldComponentUpdatecurrentupdated Prop 之间进行浅层比较。因此,在您的 PureComponent' render 中记录 console.log(this.props.item.long) 将记录可以检查的唯一列表。

关于javascript - React 中的无限渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52213596/

相关文章:

javascript - 如何在javascript中将拖放区域的宽度调整为100%

javascript - 防止 svg 组重叠(D3 js v4)

javascript - 大型生产应用程序的插入符、波形符或固定 package.json?

javascript - 如何在不触发 React 重新渲染的情况下更改元素的样式?

react-native - 使用 'create-react-native-app'时出错

android - 使用 Expo 备份 Android keystore - 我们需要保存关联的密码吗?

javascript - 将 google maps api 搜索的范围限制在一个区域

reactjs - React JS - 如何更好地将 React 组件添加到 ReactDOM

javascript - 访问 cart.order_items.length 给出 TypeError : Cannot read property 'length' of undefined

javascript - 条件在 native 生产中失败,但在开发中有效