Używam Redux. W moim reduktorze próbuję usunąć właściwość z obiektu takiego:
const state = {
a: '1',
b: '2',
c: {
x: '42',
y: '43'
},
}
I chcę mieć coś takiego bez konieczności modyfikowania pierwotnego stanu:
const newState = {
a: '1',
b: '2',
c: {
x: '42',
},
}
Próbowałem:
let newState = Object.assign({}, state);
delete newState.c.y
ale z pewnych powodów usuwa właściwość z obu stanów.
Czy może mi w tym pomóc?
javascript
immutability
redux
Vincent Taing
źródło
źródło
Object.assign
tworzy tylko płytkie kopię zstate
a zatemstate.c
inewState.c
będzie wskazywać na ten sam obiekt udostępniony. Próbowałeś usunąć właściwośćy
z udostępnionego obiektu,c
a nie z nowego obiektunewState
.Odpowiedzi:
A co powiesz na użycie składni przydziału destrukturyzacji ?
źródło
const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;
. Sposób użycia:deleteProperty({a:1, b:2}, "a");
daje{b:2}
deep['c']
jest pusty, więc w ogólnym przypadku możesz chcieć dodać sprawdzenie obecności klucza.Uważam ES5 metod tablicowych jak
filter
,map
ireduce
użyteczny, ponieważ zawsze powrócić nowych tablic lub obiektów. W tym przypadkuObject.keys
użyłbym do iteracji po obiekcie iArray#reduce
przekształcenia go z powrotem w obiekt.źródło
myObject
bez kluczamyKey
:Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
Możesz użyć
_.omit(object, [paths])
z biblioteki lodashścieżka może być zagnieżdżona na przykład:
_.omit(object, ['key1.key2.key3'])
źródło
_.omit
nie można usunąć głębokich właściwości (o co prosił OP). Doomit-deep-lodash
tego celu służy moduł._.cloneDeep(obj)
z lodash. To łatwo kopiuje obiekt, a następnie możesz po prostu użyć js,delete obj.[key]
aby usunąć klucz.Po prostu użyj funkcji destrukturyzacji obiektów ES6
źródło
const {y, ...c} = state.c
może być trochę jaśniejsze niż posiadanie dwóchc
po lewej stronie.const name = 'c'
możesz to zrobić,const {[name]:deletedValue, ...newState} = state
a następnie powrócićnewState
do swojego reduktora. To jest dla usunięcia klucza najwyższego poziomuDzieje się tak, ponieważ kopiujesz wartość
state.c
do innego obiektu. Ta wartość jest wskaźnikiem do innego obiektu javascript. Zatem oba te wskaźniki wskazują ten sam obiekt.Spróbuj tego:
Możesz także wykonać głęboką kopię obiektu. Zobacz to pytanie, a znajdziesz to, co jest dla Ciebie najlepsze.
źródło
state.c
jest odniesieniem i jest kopiowany poprawnie. Redux chce znormalizowanego kształtu stanu, co oznacza używanie identyfikatorów zamiast odniesień podczas zagnieżdżania stanu. Sprawdź dokumenty redux: redux.js.org/docs/recipes/reducers/NormalizingStateShape.htmlCo powiesz na to:
Filtruje klucz, który powinien zostać usunięty, a następnie tworzy nowy obiekt z pozostałych kluczy i obiektu początkowego. Pomysł został skradziony z programu niesamowitych reakcji Tylera McGinnesa.
JSBin
źródło
Ponadto, jeśli szukasz funkcjonalnego zestawu narzędzi do programowania, spójrz na Ramdę .
źródło
Możesz użyć pomocnika niezmienności , aby usunąć atrybut, w twoim przypadku:
źródło
Od 2019 roku inną opcją jest użycie
Object.fromEntries
metody. Osiągnął etap 4.Zaletą jest to, że ładnie obsługuje klucze całkowite.
źródło
Z Immutable.js jest to łatwe :
opis deleteIn ()
źródło
Problem, który masz, polega na tym, że nie klonujesz głęboko swojego stanu początkowego. Więc masz płytką kopię.
Możesz użyć operatora spreadu
Lub postępując zgodnie z tym samym kodem
źródło
Zwykle używam
Zdaję sobie sprawę, że w rzeczywistości nie jest to usuwanie własności, ale prawie do wszystkich celów 1 jest to równoważne funkcjonalnie. Składnia tego jest znacznie prostsza niż alternatywy, które uważam za całkiem niezły kompromis.
1 Jeśli używasz
hasOwnProperty()
, będziesz musiał użyć bardziej skomplikowanego rozwiązania.źródło
Używam tego wzoru
ale w książce widziałem inny wzór
źródło
użyteczność;))
Rodzaj działania
twórca akcji
reduktor
źródło
Jak już wskazano w niektórych odpowiedziach, dzieje się tak, ponieważ próbujesz zmodyfikować stan zagnieżdżony, tj. jeden poziom głębiej. Rozwiązaniem kanonicznym byłoby dodanie reduktora na
x
poziomie stanu:Głębszy reduktor poziomu
Oryginalny reduktor poziomu
źródło