Zacząłem więc uczyć się Reacta tydzień temu i nieuchronnie dotarłem do problemu stanu i tego, jak komponenty mają komunikować się z resztą aplikacji. Szukałem dookoła i wydaje się, że Redux jest smakiem miesiąca. Przeczytałem całą dokumentację i myślę, że to właściwie całkiem rewolucyjny pomysł. Oto moje przemyślenia na ten temat:
Ogólnie przyjmuje się, że stan jest dość zły i stanowi duże źródło błędów w programowaniu. Zamiast rozpraszać to wszystko w aplikacji, Redux mówi, dlaczego nie skupić tego wszystkiego w globalnym drzewie stanu, w którym musisz emitować akcje, aby je zmienić? Brzmi interesująco. Wszystkie programy wymagają stanu, więc umieśćmy go w jednym nieczystym miejscu i modyfikujmy go tylko od wewnątrz, aby błędy były łatwe do wyśledzenia. Następnie możemy również deklaratywnie powiązać poszczególne elementy stanu z komponentami Reacta i pozwolić im na automatyczne przerysowanie i wszystko jest piękne.
Mam jednak dwa pytania dotyczące całego projektu. Po pierwsze, dlaczego drzewo stanów musi być niezmienne? Powiedz, że nie obchodzi mnie debugowanie podróży w czasie, ponowne ładowanie na gorąco i zaimplementowałem już cofanie / ponawianie w mojej aplikacji. To po prostu wydaje się takie kłopotliwe:
case COMPLETE_TODO:
return [
...state.slice(0, action.index),
Object.assign({}, state[action.index], {
completed: true
}),
...state.slice(action.index + 1)
];
Zamiast tego:
case COMPLETE_TODO:
state[action.index].completed = true;
Nie wspominając o tym, że tworzę tablicę online tylko po to, aby się uczyć, a każda zmiana stanu może być tak prosta, jak dodanie pociągnięcia pędzla do listy poleceń. Po pewnym czasie (setki pociągnięć pędzla) kopiowanie całej tej tablicy może stać się niezwykle kosztowne i czasochłonne.
Nie przeszkadza mi globalne drzewo stanu, które jest niezależne od interfejsu użytkownika, który jest modyfikowany za pomocą działań, ale czy naprawdę musi być niezmienne? Co jest złego w takiej prostej implementacji (bardzo wstępna wersja robocza, napisana w 1 minutę)?
var store = { items: [] };
export function getState() {
return store;
}
export function addTodo(text) {
store.items.push({ "text": text, "completed", false});
}
export function completeTodo(index) {
store.items[index].completed = true;
}
Wciąż jest to globalne drzewo stanu zmutowane przez emitowane akcje, ale niezwykle proste i wydajne.
źródło
immutablejs
i użyj,return state.setIn([action.index, 'completed'], true);
aby zmniejszyć kocioł.return state.map(i => i.index == action.index ? {...i, completed: true} : i);
Odpowiedzi:
Oczywiście, że jest. Ale to samo dotyczy każdej bazy danych, z której kiedykolwiek korzystałeś. Lepiej jest traktować Redux jako bazę danych w pamięci - na której mogą reagować komponenty.
Niezmienność umożliwia sprawdzenie, czy jakiekolwiek poddrzewo zostało zmienione, bardzo wydajnie, ponieważ upraszcza do sprawdzenia tożsamości.
Tak, twoja implementacja jest wydajna, ale cały wirtualny dom będzie musiał być ponownie renderowany za każdym razem, gdy drzewo zostanie w jakiś sposób zmanipulowane.
Jeśli używasz Reacta, w końcu wykona różnicę w stosunku do rzeczywistego dom i wykona minimalne manipulacje zoptymalizowane wsadowo, ale pełne ponowne renderowanie z góry na dół jest nadal nieefektywne.
W przypadku niezmiennego drzewa komponenty bezstanowe muszą po prostu sprawdzić, czy poddrzewa, od których zależy, różnią się tożsamościami w porównaniu z poprzednimi wartościami, a jeśli tak - renderowania można całkowicie uniknąć.
źródło