Хіба Redux не просто прославляє світову державу?


84

Тож я почав вивчати React тиждень тому, і я неминуче дійшов до проблеми стану та того, як компоненти повинні взаємодіяти з рештою програми. Я шукав навколо, і Redux здається смаком місяця. Я прочитав всю документацію і думаю, що насправді це досить революційна ідея. Ось мої думки щодо цього:

Загалом держава вважається досить злим і великим джерелом помилок у програмуванні. Замість того, щоб розкидати все це по вашому додатку, Redux каже, чому б просто не сконцентрувати все це у глобальному дереві станів, яке вам потрібно виконати, щоб змінити дії? Звучить цікаво. Усі програми потребують стану, тож давайте вкладемо його в один нечистий простір і модифікуємо лише зсередини, щоб помилки було легко відстежити. Тоді ми також можемо декларативно прив’язати окремі фрагменти стану до компонентів React і зробити їх автоматичним перемальовуванням, і все прекрасно.

Однак у мене є два запитання щодо всього цього дизайну. По-перше, чому дерево держав має бути незмінним? Скажімо, я не дбаю про налагодження подорожей у часі, гаряче перезавантаження та вже застосував скасування / повтор у своєму додатку. Це просто здається таким громіздким, коли доводиться це робити:

case COMPLETE_TODO:
  return [
    ...state.slice(0, action.index),
    Object.assign({}, state[action.index], {
      completed: true
    }),
    ...state.slice(action.index + 1)
  ];

Замість цього:

case COMPLETE_TODO:
  state[action.index].completed = true;

Не кажучи вже про те, що я роблю онлайн-дошку лише для того, щоб навчитися, і кожна зміна стану може бути такою ж простою, як додавання мазка пензля до списку команд. Через деякий час (сотні мазків) дублювання всього цього масиву може стати надзвичайно дорогим і трудомістким.

Я добре з глобальним деревом станів, яке не залежить від інтерфейсу користувача, який мутується за допомогою дій, але чи справді воно має бути незмінним? Що поганого в такій простій реалізації (дуже грубий проект. Написав за 1 хвилину)?

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;
}

Це все ще глобальне дерево станів, яке мутується за допомогою випущених дій, але надзвичайно простих та ефективних.


2
"По-перше, чому дерево держав має бути незмінним?" --- тоді ви повинні надати алгоритм, щоб визначити, чи змінилися дані. Неможливо реалізувати його для довільної структури даних (якщо вона змінна). Візьміть immutablejsі використовуйте, return state.setIn([action.index, 'completed'], true);щоб зменшити шаблон.
zerkms

1
PS:return state.map(i => i.index == action.index ? {...i, completed: true} : i);
zerkms

Відповіді:


52

Хіба Redux не просто прославляє світову державу?

Звичайно. Але те ж саме стосується кожної бази даних, яку ви коли-небудь використовували. Краще розглядати Redux як базу даних у пам’яті - від якої ваші компоненти можуть реактивно залежати.

Незмінюваність дозволяє перевірити, чи будь-яке піддерево було дуже ефективно змінено, оскільки воно спрощується до перевірки ідентичності.

Так, ваша реалізація є ефективною, але весь віртуальний dom доведеться відтворювати кожного разу, коли якимось чином маніпулюють деревом.

Якщо ви використовуєте React, він врешті-решт зробить різницю по відношенню до фактичного dom і виконає мінімальні маніпуляції, оптимізовані для партії, але повний рендерінг зверху вниз все ще неефективний.

Для незмінного дерева компоненти без стану просто повинні перевірити, чи піддерево (дерева), від якого воно залежить, відрізняються ідентичностями порівняно з попередніми значеннями, а якщо так - то рендерингу можна повністю уникнути.


3
Хіба це не трохи передчасної оптимізації? Крім того, звідки ми знаємо, що вартість постійного тиражування незмінних об'єктів менша, ніж повторне відображення DOM (також віртуальний DOM React сильно не зменшить цю вартість?)
Райан Пешель,

3
Ну, бібліотеки графічного інтерфейсу користуються такою оптимізацією протягом тривалого часу (див. Bitquabit.com/post/the-more-things-change ). змінюється, лише одному ланцюжку батьків потрібно ланцюг - решта вузлів залишаються незмінними. Таким чином, ми не дублюємо всю структуру даних для кожної дії - ми повторно використовуємо підкомпоненти, які не змінилися, для побудови нової структури даних.
lorefnon

4
Також Reacts Virtual DOM не зовсім темна магія - Цитата з React docs: "Генерування мінімальної кількості операцій з перетворення одного дерева в інше є складною і добре вивченою проблемою. Сучасні алгоритми мають складність у порядку з O (n3), де n - кількість вузлів у дереві. "
lorefnon

2
Причина, по якій React може працювати набагато краще на практиці, полягає в тому, що: React покладається на евристику - отже: "Якщо ви не надаєте стабільні ключі (наприклад, за допомогою Math.random ()), усі піддерева збираються буде надаватися повторно кожен раз. Надаючи користувачам можливість вибору ключа, вони мають можливість стріляти собі в ногу ". Так само, як ви можете допомогти React, надаючи стабільні ключі, так само ви можете допомогти React, надаючи незмінний реквізит даних.
lorefnon

1
Щодо вашого масиву мазків пензля - будь ласка, зверніться: facebook.github.io/immutable-js/docs/#/List Цитування з документів: Списки впорядковані індексовані щільні колекції, подібно до масиву JavaScript. Списки реалізують Deque, з ефективним додаванням і видаленням як кінця (натискання, натискання), так і початку (зрушення, зміщення).
lorefnon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.