【问题标题】:React Native: renderRow not executedReact Native:未执行渲染行
【发布时间】:2015-06-23 15:17:01
【问题描述】:

在下面的代码中,当从campaignsUpdated 调用setState 时,render 被记录到控制台,而不是renderRow

var React = require('react-native'),

Bus = require('../Bus'),
styles = require('../Styles'),
CampaignsStore = require('../stores/Campaigns'),
CampaignItem = require('./CampaignItem'),

{
  Component,
  Text,
  TextInput,
  ListView,
  View,
  NavigatorIOS,
  ActivityIndicatorIOS
} = React


class CampaignList extends Component {
    constructor(props) {
      super(props)

      this.state = {
        dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
      }
    }

    componentDidMount() {
      this.addListeners()
      Bus.emit('campaigns:search', '')
    }

    componentWillUnmount() {
      this.removeListeners()
    }

    render() {
      console.log('render')
      return (
        <View style={styles.container}>
          <TextInput
            style={styles.searchInput}
            placeholder='Campaign Name'
            value={this.state.campaignName}
            onChange={this.campaignSearchChanged.bind(this)}/>
          <ListView
            dataSource = {this.state.dataSource}
            renderRow = {this.renderRow.bind(this)}/>
        </View>
      )
    }

    renderRow(campaign) {
      console.log('renderRow')
      return <CampaignItem campaign={campaign}/>
    }

    addListeners() {
      Bus.on({
        'campaigns:updated': this.campaignsUpdated.bind(this)
      })
    }

    removeListeners() {
      Bus.off({
        'campaigns:updated': this.campaignsUpdated.bind(this)
      })
    }

    campaignsUpdated(event) {
      var campaigns = event.data
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(campaigns)
      })
    }

    campaignSearchChanged(event) {
      var campaignName = event.nativeEvent.text
      Bus.emit('campaigns:search', campaignName)
    }
}

module.exports = CampaignList

我在这里做错了什么?

【问题讨论】:

    标签: javascript reactjs react-native


    【解决方案1】:

    您正在向ListView 传递一个返回组件的函数renderRow。一旦通过,您将不得不在ListView 内调用该函数,大概是在campaigns 上的映射期间。

    【讨论】:

    • 另外,您似乎正在调用this.renderRow.bind(this),但我看不出将上下文传递给renderRow 的原因。
    • 为什么我必须调用renderRow?它第一次正确呈现,所以我假设 ListView 映射到你提到的活动,而组件不必这样做。
    • 哎呀错过了这是本机反应抱歉。一定没有点击rowHasChanged 函数,因为您的数据没有改变或者cloneWithRows 没有触发rowChange?
    【解决方案2】:

    从外观上看,最有可能的情况是您在这里遇到了经典的 React 可变性问题。

    即我怀疑您的“campaignsUpdated”方法是使用上次收到的相同 Array 实例调用的,或者列表中的元素是相同的实例。

    尝试使用:

    campaignsUpdated(event) {
      var campaigns = event.data.slice(); // <-- clone the array
      this.setState({
        dataSource: this.state.dataSource.cloneWithRows(campaigns)
      })
    }
    

    如果这不起作用,那么您要么让管理您的竞争列表的部分在进行更改时创建新副本(例如const clone = {...campaign, title:"A new Title"}),要么更新您的 rowHasChanged 方法以查看标题(或您的任何数据)需要)实际上已经改变了。

    这里有两个关于 JavaScript 不变性的非常好的视频: https://egghead.io/lessons/javascript-redux-avoiding-array-mutations-with-concat-slice-and-spread https://egghead.io/lessons/javascript-redux-avoiding-object-mutations-with-object-assign-and-spread

    【讨论】:

      猜你喜欢
      • 2020-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 2020-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多