从 Array in ScrollView 中删除子项总是删除最后一项

Removing children from Array inside ScrollView always deletes last item

我有

<ScrollView horizontal={true} >
  {this.state.images.map((uri,i) => 
  <Thumb key={i} number={i} uri={uri} onDelete ={this.deleteImage.bind(this)} /> )}
</ScrollView>

这里每个Thumbclass有Image。每当我单击图像时,都需要将其从 ScrollView.

中删除

我的 Thumb 组件看起来像这样

 class Thumb extends React.Component {
constructor(props){
  super(props);

  this.state = {
    show : false
  }
}


  shouldComponentUpdate(nextProps, nextState) {
    console.log(nextProps,'nextprops')
    return false;
  }
  render() {
    return (
      <View style={[styles.button ]}>


            <View style={[{position:'relative'},styles.img]} >
              <View style={{position:'absolute'}}>
                <Image style={styles.img} source={{uri:this.props.uri.path}}/>
              </View>

              <View style={[styles.img , {position:'absolute',alignItems:'center',justifyContent:'center',opacity:1}]}>

              <TouchableHighlight onPress = {() => {this.props.onDelete(this.props))}}>
                <Icon name="close" size = {30} color="white"/>
                 </TouchableHighlight>
              </View>
            </View>

      </View>
    );
  }
}

我正在尝试删除

deleteImage(deleteProp){
//  console.log(_scrollView)
//  _scrollView.props.children.splice(deleteProp.number,1)
//  console.log(_scrollView)
  console.log(deleteProp,'prop from delete method');
   console.log(this.state.images ,'before')
 let images = this.state.images;
 console.log(images.splice(deleteProp.number ,1),'splice data');
  this.setState({images : images});
 console.log(this.state.images,'after')
  if(this.state.images.length == 0 ){
    this.setState({loading:false})
  }
}

我该如何实现?

我尝试删除相应的状态图像对象,但它总是删除 ScrollView(或最后一个 Thumb 组件)的最后一个图像。

我是 react-native 的新手,Android 我不知道 ScrollView 是否可行。请建议我正确的方法。

这是一个非常常见的问题,混淆了 keys 在组件中扮演的角色。我们将键视为动态生成组件的唯一标识符。但它也可以作为 React 了解哪些组件需要重绘的一种方式。

因此,我建议您将 key 更改为图像本身所独有的东西,而不是位置。

<Thumb key={uri.path} number={i} uri={uri} onDelete={this.deleteImage.bind(this)} />

Here's the official docs on keys.

The key only has to be unique among its siblings, not globally unique. As a last resort, you can pass item's index in the array as a key. This can work well if the items are never reordered, but reorders will be slow. (emphasis mine).

This is another good article about why keys are important.

此外,当您有生成组件的数组时,我喜欢 "preload" 函数不需要传递给它的索引、id 等。

// original component
<Thumb key={i} number={i} uri={uri} onDelete={this.deleteImage.bind(this)} />
// updated function by adding index to bind params and unique key
<Thumb key={uri.path} number={i} uri={uri} onDelete={this.deleteImage.bind(this,i)} />

这样,当你想删除时,你可以简单地调用this.props.onDelete()。只是一个偏好,但我认为它更干净。

拇指:

class Thumb extends React.Component {
    constructor(props){
        super(props);

        this.state = {
            show : false
        }
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log(nextProps,'nextprops')
        return false;
    }

    render() {
        return (
            <View style={[styles.button ]}>
                <View style={[{position:'relative'},styles.img]} >
                    <View style={{position:'absolute'}}>
                        <Image style={styles.img} source={{uri:this.props.uri.path}}/>
                    </View>
                    <View style={[styles.img , {position:'absolute',alignItems:'center',justifyContent:'center',opacity:1}]}>
                        <TouchableHighlight onPress = {this.props.onDelete}>
                            <Icon name="close" size = {30} color="white"/>
                        </TouchableHighlight>
                    </View>
                </View>
            </View>
        );
    }
}

滚动视图

<ScrollView horizontal={true} >
    {this.state.images.map((uri,index) => 
    <Thumb key={index} uri={uri} onDelete={this.deleteImage.bind(this, index)}/> )}
</ScrollView>

deleteImage()

deleteImage(index) {
    const images = this.state.images;
    const newImages = [...images.slice(0, index), ...images.slice(index + 1, images.length)];
    let newState = { images: newImages };

    if(images.length === 0){
        newState = { ...newState, loading: false };
    }

    this.setState(newState);
}