2016-11-17 2 views
0

У меня естьУдаление детей из массива внутри ScrollView всегда удаляет последний элемент

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

Как я этого добиться?

Я попытался удалить соответствующий объект состояния, но всегда удаляет последнее изображение ScrollView (или последнего компонента Thumb).

Я новичок в реагировании на родной язык и Android. Я не знаю, что это возможно с помощью ScrollView. Пожалуйста, предложите мне правильный метод.

+0

Можете ли вы опубликовать код, чтобы удалить запись из state.images? Обычно вы хотите передать индекс/id элемента, который хотите удалить, например '' 'this.deleteImage.bind (this, i)' '', чтобы вы знали, какой из них удалить. –

+0

@ fabio.sussetto Я передаю индекс, чтобы удалить изображение – santhosh

+0

@ fabio.sussetto let images = this.state.images; images.splice (deleteProp.number, 1); this.setState ({images: images}); – santhosh

ответ

0

Это довольно распространенная проблема с запутанностью роли 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.

Кроме того, когда у вас есть массивы, которые генерируют компоненты, мне нравится «предварительно загружать» функции, не требующие индексов, идентификаторов и т. Д., Переданных ей.

// 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(). Просто предпочтение, но я думаю, что он чище.

0

большого пальца руки:

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

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