S
S
sergemin2017-09-24 10:10:41
JavaScript
sergemin, 2017-09-24 10:10:41

How to correctly remove an element from an array?

Good afternoon!
I'm working with Redux right now and I can't correctly remove the desired element from the array.
Let's say I have an array that is stored in store. This array is mapped out as a list. Each list element has a delete button, on which I hung a handler and pass its index as a callback

removeStudent(index) {
        this.props.onRemoveStudent(index);
    }
render() {
return (
{this.props.studentsStore.studentsList.map((item, index) =>
                                <tr className="itemStudent" key={index}>
                                    <td><input type="text" defaultValue={item.name} /></td>
                                    <td><input type="text" defaultValue={item.surname} /></td>
                                    <td>{item.gender}</td>
                                    <td><input type="text" defaultValue={item.age} /></td>
                                    <td>{item.isMarried + ''}</td>
                                    <td><button id="remove" onClick={() => this.removeStudent(index)}>X</button></td>
                                </tr>
                            )}
)
}

But it's impossible to write the necessary reducer.
With the addition, it's clear, it's just to insert one more element at the end of the array. Here's how to delete...
export default connect(
    state => ({
        studentsStore: state
    }),
    dispatch => ({
     
        onRemoveStudent: (index) => {
            dispatch({ type: 'REMOVE_STUDENT', payload: index })
        }
    })

So here is my reducer
export default function studentsList(state = initialState, action) {
    if(action.type === 'ADD_STUDENT') {
        return [
            ...state,
            action.payload
        ]
    }
    if(action.type === 'REMOVE_STUDENT') {
        let newArr = state;
        newArr.splice(action.payload, 1);
        return newArr.filter(element => element !== action.payload);
    }
    return state;
}

Now only the last element is deleted, regardless of which element was
clicked Please tell me

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Maxim, 2017-09-24
@sergemin

Since you always need to return a new array, the task can be divided as follows:
1) copy * everything from the beginning to index
into the new array 2) copy everything from index + 1 to the end
* into the same new array - spread operator is great for copying . In theory it looks like this:

const arr = [{a:1},{b:2},{c:3},{d:4}]
//допустим, вы прислали index 1 и сохранили его в переменную index, например
const newArr = [
  ...arr.slice(0, index), // клонируем все элементы до индекса
  ...arr.slice(index+1), // клонируем все элементы после индекса
  // итого: индексный элемент удален
]

Hazrat Gadzhikerimov correctly told you about the filter as well. I gave the correct answer in the comment. Let's take a look at yours now:
if(action.type === 'REMOVE_STUDENT') {
        let newArr = state; // сохранили в newArr ссылку(!!!) на старый массив. Если вы хотели скопировать массив, то нужно было писать: let newARr = [...state] (если в state просто массив)
        newArr.splice(action.payload, 1); // здесь вы из newArr ( и из state, так как сохранили ссылку) удалили с ИНДЕКСА один элемент. Так же, внимание, вы используете sPlice, а не slice. Разницу нужно уточнить! (подсказка ниже как)
        return newArr.filter(element => element !== action.payload); // а здесь вы что вообще написали? вы сравнили element (что там? объект?) с action.payload (в которой как вы говорите индекс). Что должно быть в итоге? ;)
    }

It is very easy to google all unfamiliar functions by type: name MDN
in your case queries to google:
slice MDN (first issue link )
filter MDN (first issue link )
Theory that does not understand: copying objects by reference

H
Hazrat Hajikerimov, 2017-09-24
@hazratgs

You are modifying the state, since arrays are passed by reference, in my opinion filter() is enough and there is no need for splice

A
Alexander Zolotarev, 2017-09-24
@argonavtt

As far as I understand, you have a problem with comparing two objects. filter doesn't consider them the same, read about comparing objects in javascript

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question