Состояние меняется само собой? - PullRequest
2 голосов
/ 10 января 2020

У меня есть обработчик изменений React, наблюдающий за серией флажков. Цель состоит в том, чтобы иметь в состоянии массив всех «проверенных» записей. Сначала обработчик копирует текущее состояние в переменную локального массива. Затем он проверяет наличие проверок и либо помещает новую запись в переменную, либо склеивает ее из переменной. Наконец, он устанавливает эту переменную обратно в состояние, готовое к следующему циклу.

Проблема в том, что мой массив в состоянии автоматически меняет сразу при изменении локального массива. Как это могло произойти?!?!

Вот мой код обработчика:

    handleEmpChange(parm1, parm2, event) {
        const {name, value, checked} = event.target
        console.log("name: ",name)
        console.log("value: ",value)
        console.log("checked: ",checked)

        // Add the checked employee into the array (or remove it if unchecked)
        let employeesArray = this.state.assignedTo
        if (checked) {
            console.log("employeesArray - before push: ",employeesArray)
            console.log("this.state.assignedTo - before push: ",this.state.assignedTo)
            console.log("this.state.originalAssignedTo - before push: ",this.state.originalAssignedTo)
            employeesArray.push(value)
            console.log("employeesArray - after push: ",employeesArray)
            console.log("this.state.assignedTo - after push: ",this.state.assignedTo)
            console.log("this.state.originalAssignedTo - after push: ",this.state.originalAssignedTo)
        } else {
            // Find the index of the unchecked employee, then splice it out of the array
            console.log("employeesArray - before splice: ",employeesArray)
            console.log("this.state.assignedTo - before splice: ",this.state.assignedTo)
            console.log("this.state.originalAssignedTo - before splice: ",this.state.originalAssignedTo)
            employeesArray.splice(employeesArray.indexOf(value),1)
            console.log("employeesArray - after splice: ",employeesArray)
            console.log("this.state.assignedTo - after splice: ",this.state.assignedTo)
            console.log("this.state.originalAssignedTo - after splice: ",this.state.originalAssignedTo)
        }
        this.setState({assignedTo: employeesArray})

    }

А вот и вывод журнала консоли:

name:  emp_1
value:  dlynn2614
checked:  true
employeesArray - before push:  ["dsmith"]
this.state.assignedTo - before push:  ["dsmith"]
this.state.originalAssignedTo - before push:  ["dsmith"]
employeesArray - after push:  (2) ["dsmith", "dlynn2614"]
this.state.assignedTo - after push:  (2) ["dsmith", "dlynn2614"]
this.state.originalAssignedTo - after push:  (2) ["dsmith", "dlynn2614"]

Обратите внимание на последнее две записи в журнале: и this.state.assignedTo, и this.state.originalAssignedTo имеют новую запись "dlynn2614", хотя операция pu sh была выполнена только для локального массива employeeArray. Это разрушает мой более поздний тест, сравнивающий this.state.assignedTo с this.state.originalAssignedTo для идентификации новых сотрудников (для получения уведомлений по электронной почте о том, что они были добавлены в эту запись).

Та же проблема возникает в «else «условие: удаленная запись вырезана как из локального массива, так и из массивов состояний.

При тестировании я создал до трех массивов состояний, все инициализированные из одной и той же начальной точки (возврат из Ax ios вызов базы данных, которая заполняет выбранных в данный момент сотрудников). Все три массива состояний изменяются синхронно c с локальной переменной. Поля состояний, которые не заполняются из одного источника, не затрагиваются.

Поддерживает ли локальный массив ссылку на соответствующие ему массивы (и) состояний? Я настроил ту же ситуацию с полем в виде простого текста и не получил те же результаты: изменение локальной переменной не повлияло на состояние. Похоже, что массив связан с этим.

Мои товарищи по команде и я весьма озадачены этим. Любое понимание будет приветствоваться.

Спасибо!

1 Ответ

5 голосов
/ 10 января 2020

Вместо let employeesArray = this.state.assignedTo попробуйте let employeesArray = [...this.state.assignedTo]. Это создаст новый массив вместо ссылки на текущий в состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...