4

Я пытался отладить странную проблему, и я, наконец, понял, почему это происходит. Просто не знает, как предотвратить это (у меня есть эта функция:Как предотвратить мутацию объекта/массива

getInfo(id) { 
    id = id || "zero"; 
    let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id))); 
    // console.log(i) - works in plunker 
    // but in my app sometimes returns -1... 
    let current = routeDefinitions[i]; 
    let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false; 
    let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false; 
    return { prev, current, next }; 
} 

..Это отлично работает в this plunker, но в моем приложении я использую возвращаемое значение для обновления приложения состояния (пользовательской реализации Redux шаблона). При отправке возвращаемого значения через эту функцию:

private _update(_old, _new) { 
    let newState = Object.keys(_new) 
     .map(key => { 
     if (_old[key] === undefined) { 
      _old[key] = _new[key]; 
     } else if (typeof _new[key] === "object") { 
      this._update(_old[key], _new[key]); 
     } else { 
      _old[key] = _new[key]; 
     } 
     return _old; 
     }) 
     .find(Boolean); 

    return Object.assign({}, newState || _old); 
    } 

.. routeDefinitions массив мутировал и вещи начинают ломаться ... Я пытался несколько вещей:

let current = [...routeDefinitions][i]; 
// and: 
return Object.assign({}, { prev, current, next }); 

.. но это не сработало. Как предотвратить мутацию массива routeDefinitions?

EDIT: мне удалось воспроизвести ошибку в this plunker

+0

Вы можете использовать Object.freeze, но это может привести к другим проблемам, если один из других методов ожидает, что это будет изменчивым. В этом случае лучше всего отправить копию. – toskv

+0

Можете ли вы указать ошибку/проблему, которую вы получаете, и plnkr с воспроизведением той же проблемы? –

+0

Я получаю '~ .current.name' не может получить имя undefined (перефразирование), когда я добавляю' if (i === -1) console.log (i, routeDefinitions.map (r => r.name)); 'в getInfo(), ниже' let i' Я вижу, что массив мутирован. Я попытаюсь обновить плункер и как-то включить '_update()', я достаточно уверен, что есть ... – Sasxa

ответ

0

Я решил эту проблему путем изменения _update() вроде этого:

private _update2(_old, _new) { 
    let newState = {}; 
    Object.keys(_new) 
     .map(key => { 
     if (_old[key] === undefined) { 
      newState[key] = _new[key]; 
     } else if (typeof _new[key] === "object") { 
      newState[key] = this._update2(_old[key], _new[key]); 
     } else { 
      newState[key] = _new[key]; 
     } 
     return newState; 
     }) 
     .find(Boolean); 

    return Object.assign({}, _old, newState); 
    } 

Я использую old state только для проверки значений, не не изменять его, пока позже, когда _update() закончена.

Plunker

0

routeDefinitions массива мутируют и вещи начинают ломаться

Если функция действительно:

getInfo(id) { 
    id = id || "zero"; 
    let i = routeDefinitions.findIndex(r => Boolean(r.name.toLowerCase().match(id))); 
    // console.log(i) - works in plunker 
    // but in my app sometimes returns -1... 
    let current = routeDefinitions[i]; 
    let next = routeDefinitions[i + 1] ? routeDefinitions[i + 1] : false; 
    let prev = routeDefinitions[i - 1] ? routeDefinitions[i - 1] : false; 
    return { prev, current, next }; 
} 

Затем routeDefinitionsне является мута ted. Что-то еще является mutating routeDefinitions.