0

我正在处理<ListView>组件,我有一个名称列表,但是在更改状态后,它正在更改值,但它没有重新渲染 ListView。

isSelect:false - (状态)

在此处输入图像描述

isSelect:true - (状态)

在此处输入图像描述

代码:

var designerName = [{id: 'Calvin Klein', name: 'Calvin Klein', isSelected: false},
                {id: 'Donatella Versace', name: 'Donatella Versace', isSelected: false},
                {id: 'Valentino Garavani', name: 'Valentino Garavani', isSelected: false},
                {id: 'Giorgio Armani', name: 'Giorgio Armani', isSelected: false}];

export default class filter extends Component {
    constructor() {
        super();
        const listDs = new ListView.DataSource({
            rowHasChanged: (r1, r2) => r1 !== r2,
        });
        this.state = {
            listDs:designerName
        };
    }

componentDidMount(){
   this.setState({
    designerDataSource:this.state.designerDataSource.cloneWithRows(this.state.listDs),
    })
}

render() {
    return (
        <View>
            <ListView
                dataSource={this.state.designerDataSource}
                renderRow={this.renderRow.bind(this)}
            />
        </View>
    );
}

renderRow(item){
    return (
        <TouchableHighlight key={item.id} onPress={this.onItemDesigner.bind(this, item)}>
                <View>
                    <View>
                        {this.renderName(item)}
                    </View>
                    <View>
                        <Text>{item.name}</Text>
                    </View>
                </View>
            </TouchableHighlight>
    );
}

renderName(item){
    if(item.isSelected) {
        return(
            <Image 
                style={{
                    width: 15,
                    height:15}} 
                source={require('../images/black_tick_mark.png')} />
        );
    }
}

onItemDesigner(item){
    var tempDesigner = this.state.listDs.slice();

    for(var i=0; i<tempDesigner.length; i++){
        if (tempDesigner[i].id == item.id && !tempDesigner[i].isSelected) {
            tempDesigner[i].isSelected = true;
        }else if (tempDesigner[i].id == item.id && tempDesigner[i].isSelected){
            tempDesigner[i].isSelected = false;
        }   
    }
    this.setState({
        designerDataSource: this.state.designerDataSource.cloneWithRows(tempDesigner),
    });
   }
}

请仔细阅读我上面的代码,如果您找到任何解决方案,请告诉我。

谢谢

4

1 回答 1

0

问题部分是 Javascript,部分是 ListView。当您构造 ListView.DataSource 时,它​​源于此函数。

const listDs = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2,
});

rowHasChanged控制是否应该进行渲染,它检查旧对象是否等于新对象。

如果其中一项已更改,则将两个对象一起比较不会返回 false。它正在检查实际对象本身是否指向不同的内存位置。

考虑这些例子。

let array1 = [{foo: 'bar'}]
let array2 = array1.slice()
// sliced array still contains references to the items
console.log(array2[0] === array1[0])
// => true

// change something in array1
array1[0].foo = 'test'
// you'll see the change in array2 as well
console.log(array2[0].foo)
// => 'test'

要使其具有新的变量位置,您可以创建一个空的 {} 对象并遍历原始键并将键/值保存到新的键/值,或者使用更简单的方法JSON.parse(JSON.stringify(obj))来克隆对象。

array2[0] = JSON.parse(JSON.stringify(array1[0]))
console.log(array2[0] === array1[0])
// => false

从技术上讲,您可以通过这种方式克隆整个阵列,或者只克隆一个发生变化的阵列。我想只对更改的对象执行此操作以防止不需要的渲染会更有效。

查看JavaScript 中的对象相等性

于 2016-12-02T13:19:26.790 回答