【问题标题】:Removing children from Array inside ScrollView always deletes last item从 ScrollView 内的 Array 中删除子项总是会删除最后一项
【发布时间】:2016-11-17 09:50:52
【问题描述】:

我有

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

这里每个Thumb 类都有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})
  }
}

我应该如何做到这一点?

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

我是 react-native 和 Android 的新手,我不知道 ScrollView 可以做到这一点。请建议我正确的方法。

【问题讨论】:

  • 您可以发布代码以从 state.images 中删除条目吗?通常你想传递你想删除的项目的索引/ID,比如this.deleteImage.bind(this, i),这样你就知道要删除哪个了。
  • @fabio.sussetto 我正在传递索引以删除图像
  • @fabio.sussetto let images = this.state.images; images.splice(deleteProp.number ,1); this.setState({images : images});
  • 一些事情:1)splice 改变了 this.state.images 的内容。在 React 中,你不应该直接改变状态,而是使用 Array#slice。 2)你如何更新deleteProp?如果可以,请发布完整的组件类,以便我们了解发生了什么。
  • @fabio.sussetto 我已经更新了代码...

标签: android reactjs react-native react-native-scrollview


【解决方案1】:

这是一个很常见的问题,混淆了keys 在组件中的作用。我们认为键只是动态生成的组件的唯一标识符。但它也可以作为 React 知道哪些组件需要重绘的一种手段。

因此,我建议将您的 key 更改为图像本身的独特之处,而不是位置。

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

Here's the official docs on keys.

键只需要在其兄弟中是唯一的,而不是全局唯一的。作为最后的手段,您可以将数组中的项目索引作为键传递。 如果项目从不重新排序,这会很好用,但重新排序会很慢。 (强调我的)。

This is another good article about why keys are important.

此外,当您有正在生成组件的数组时,我喜欢“预加载”这些函数,以便不需要传递给它的索引、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()。只是一种偏好,但我认为它更干净。

【讨论】:

    【解决方案2】:

    拇指

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 2020-11-30
      • 2020-07-07
      • 2011-05-25
      • 1970-01-01
      • 2020-05-09
      相关资源
      最近更新 更多