2016-02-11 4 views
3
var ListItem = require('./listItem'); 

    var App = React.createClass({ 
    getInitialState : function(){ 
     return{ 
     items : [] 
    } 
    }, 

    deleteElement: function(){ 
    }, 

    addElement : function(){ 
     this.state.items.push(<ListItem />); 
     this.forceUpdate(); 
    }, 

    render : function(){ 
     return (
      <div> 
       <ul>{this.state.items.map(function(item,i){return (
       <li> 
        <p onClick='this.deleteElement'>(-)</p> 
        {item} 
       </li> 
      )})}</ul> 
      <p onClick='this.addElement'>(+)</p> 
      </div> 
     ); 
    } 
    }); 

В настоящее время я могу добавить li элементы массива с помощью addElement function .Но не могу понять, как удалить конкретный li элемент из ul списка, нажав на deleteElement function .I попытался с помощью splice(), но не работает . Я новичок в reactjs.So не знаю, как удалить элементы li на клик в реагировании.Как удалить элемент li на клик из списка в responsejs?

ответ

2

В коде есть несколько ошибок

  1. не использовать this.forceUpdate();, вместо этого вы должны использовать setState

  2. к onClick вы должны передать ссылку функционировать не

    снабжать струной, тетивой и т.п.
  3. 'this.addElement'

Теперь рассмотрим, как вы можете удалить элемет из списка. Вам необходимо пройти до deleteElement индекс this.deleteElement.bind(this, i) и удалить элемент по индексу из items массива, а затем установить новое состояние

var App = React.createClass({ 
    getInitialState : function(){ 
    return { 
     items : [] 
    } 
    }, 

    deleteElement: function(index) { 
    this.setState({ 
     items: this.state.items.filter(function (e, i) { 
     return i !== index; 
     }) 
    }); 
    }, 

    addElement: function() { 
    this.setState({ 
     items: this.state.items.concat(<ListItem time={ +new Date() } />) 
    }); 
    }, 

    render: function() { 
    var list = this.state.items.map(function(item, i) { 
     return <li key={ i }> 
     <p onClick={ this.deleteElement.bind(this, i) }>(-)</p> 
     <span>{ item }</span> 
     </li> 
    }, this); 

    return <div> 
     <ul>{ list }</ul> 
     <p onClick={ this.addElement }>(+)</p> 
    </div> 
    } 
}); 

Example

+0

Ваша скрипка работает отлично.Точно, что мне нужно. Но мой код такой же, как у вас в скрипке. Но когда я нажимаю (-), всегда удаляется последний элемент в списке. –

+0

@Vishwasraj Не могли бы вы создать скрипку с кодом? Я проверю его –

+0

https://jsfiddle.net/vishwasrajt/cwqx5g67/ –

0

На вашей карте при настройке обратного вызова deleteElement перейдите в индекс текущего элемента.

<p onClick={ function() { this.deleteElement(i) } }>(-)</p> 

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

deleteElement: function(index){ 
    var items = this.state.items; 
    var leftSide = items.slice(0, index); 
    var rightSide = items.slice(index + 1, items.length); 
    this.setState({ items: leftSide.concat(rightSide) }); 
} 

slice предпочтительно splice, потому что slice не мутируют существующий массив. Здесь мы создаем новый массив и избегаем любых мутаций.

Если вы используете ES6 это может быть несколько снижено:

<p onClick={() => this.deleteElement(i) }>(-)</p> 

deleteElement: (index) => { 
    var items = this.state.items; 
    var leftSide = items.slice(0, index); 
    var rightSide = items.slice(index + 1, items.length); 
    this.setState({ items: [...leftSide, ...rightSide] }); 
} 

После того, как обратная сторона знать при этом, функции окружающих deleteElement в вашем JSX будет воссоздана на каждом render. Это создает больше работы для сборщика мусора, потому что в памяти будет множество неиспользуемых указателей функций.

0

Вот что бы я сделал ...

remove(idx) { 
    return (event) => { 
    // Concatening original items array returns new array - this is important! 
    const items = this.state.items.concat(); 
    items.splice(idx, 1); 
    this.setState({ items }); 
    } 
}, 

render() { 
    return (
    <div> 
     ... 
     <ul> 
     { this.state.items.map((item, i) => <Item key={i} remove={this.remove(i)} text={item} />) } 
     </ul> 
     ... 
    </div> 
); 
} 

Здесь вы передаете индекс элемента, который вы хотите удалить. Конечно, функция вызова не была бы хорошей в рендеринге - она ​​удаляла бы все элементы рендера (на самом деле, вы не должны изменять состояние в методе рендеринга). Вместо этого вы возвращаете функцию, которая будет выполняться при нажатии.

компонент товара может выглядеть примерно так:

const Item = React.createClass({ 
    render() { 
    return (
     <li> 
     { this.props.text } 
     <span onClick={this.props.remove}>&times;</span> 
     </li> 
    ); 
    } 
}); 

Работа скрипку здесь ... https://jsfiddle.net/69z2wepo/31009/

+0

'{this.remove (i)}' будет запускать функцию удаления до щелчка, не так ли? Обработчику нужно передать функцию. –

+0

Нет, не будет. Пожалуйста, внимательно прочитайте. 'this.remove (i)' возвращает функцию, которая вызывается при нажатии. Взгляните на пример Fiddle, поиграйте с ним :) – Andreyco

+1

Я вижу. Я не заметил, что 'remove' был функцией более высокого порядка. Спасибо за разъяснения! –

Смежные вопросы