В чем заключается эта разница между этим действием потока и вызовом этой функции?

Я мог бы иметь такое действие потока:

{type: 'KILL', payload: {target: 'ogre'}}

Но я не вижу, какая разница между тем, как метод для класса People (обертывание магазина), например,

People.kill('ogre') 

IF Люди являются единственным получателем действия?

Я вижу, что диспетчер потоков дает мне два преимущества (возможно)

  • Метод "kill" может быть передан нескольким неизвестным приемникам (хорошо!)
  • Диспетчер дает мне удобное место для регистрации всего трафика действий (также хорошо!)

Это могут быть хорошие вещи, но есть ли другие причины, по которым мне не хватает?

То, что я не вижу, - это то, как переносить действия в виде объектов JSON, внезапно принуждает или помогает с "односторонним" потоком связи, который я читаю повсюду, - это большое преимущество наличия действий и поток.

Мне кажется, что я все еще эффективно отправляю сообщение в магазин, независимо от того, как я духи свинью. Конечно, действие теперь проходит через пару уровней косвенности (создатель действия, диспетчер), прежде чем он попадет в хранилище, но если я не упустил что-то, компонент, который отправляет это действие для всех практических целей, обновляет все магазины, которые прослушивают убить сообщение.

Что мне здесь не хватает?

Снова я знаю о переполнении стека, мы не можем задавать слишком общий вопрос, поэтому я хочу сохранить это очень конкретным. Два фрагмента кода с разным синтаксисом кажутся семантически (за исключением возможности трансляции в несколько хранилищ) точно так же.

И снова, если единственная причина в том, что он позволяет широковещательную рассылку и позволяет использовать одну точку потока для отладки, я в порядке с этим, но хотел бы знать, есть ли какая-то другая информация о flux/диспетчере, которого я пропускаю

Ответ 1

Основные особенности архитектуры стиля потока - примерно следующее:

  • магазин является единственным источником правды для состояния приложения.
  • только действия могут вызывать мутацию состояния хранилища.
  • Состояние хранилища не должно быть мутировано напрямую, то есть посредством назначения значений объекта, но путем создания новых объектов путем клонирования/деструктурирования вместо

Как и в случае с диетой, использование такого типа архитектуры действительно не сработает, если вы соскользните и вернетесь к старым путям с перерывами.

Возврат к вашему примеру. Преимущество использования этого действия здесь не в аспектах вещания или регистрации, а просто в том, что класс People должен иметь возможность либо потреблять данные из магазина, либо выражать свои пожелания по изменению состояния указанного хранилища с действиями. Представьте себе, например, что Elves хотят петь людоеду и поэтому заинтересованы в том, чтобы знать, что огр все еще жив. В то же время People хотят быть вежливыми и не хотят убивать людоедов, пока они серенады. Преимущества архитектуры в стиле потока очевидны:

class People {
  kill(creature) {
    if (creatureStore.getSerenadedCreature() !== creature)
      store.dispatch({ type: 'KILL', payload: { target: creature } })
    return `The ${creature} is being serenaded by those damn elves, let wait until they've finished.`
  }
}

class Elves {
  singTo(creature) {
    if (!creatureStore.getCreatures().includes(creature))
      return store.dispatch({ type: 'SING_TO', payload: { target: creature } })
    return `Oh no, the ${creature} has been killed... I guess there will be no serenading tonight..`
  }
}

Если класс People должен был обернуть хранилище, вам понадобится класс Elves для того, чтобы обернуть тот же магазин, создав два места, где одно и то же состояние будет мутировано так или иначе. Теперь представьте, есть ли еще 10 классов, которым нужен доступ к этому магазину, и хотите изменить его: добавление этих новых функций становится больно, потому что все эти классы теперь во власти других классов, которые мутируют состояние из-под них, заставляя вас для обработки тонны краевых случаев, возможно, даже не связанных с бизнес-логикой этих классов.

С архитектурой стиля потока все эти классы будут потреблять только данные из creatureStore и действия отправки на основе этого состояния. В хранилище обрабатываются различные действия с состоянием, чтобы все его подписчики имели правильные данные в нужное время.

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

Надеемся, что этот стенографический текст помог прояснить!

Ответ 2

То, что я не вижу, - это то, как переносить действия в виде объектов JSON, внезапно принуждает или помогает с "односторонним" потоком связи, который я читаю повсюду, - это большое преимущество наличия действий и поток. Мне кажется, что я все еще эффективно отправляю сообщение обратно в магазин, как бы я ни душил свинью. Конечно, действие теперь проходит через пару уровней косвенности (создатель действия, диспетчер), прежде чем он попадет в хранилище, но если я не упустил что-то, компонент, который отправляет это действие для всех практических целей, обновляет все магазины, которые прослушивают убить сообщение. Что мне здесь не хватает?

Facebook Flux взял на себя эту идею из управляемых событиями графических интерфейсов. Там, даже если вы двигаете мышью, вы получаете сообщения. Затем это называлось конвейером сообщений, и теперь у нас есть действия, отправляемые.

Кроме того, у нас есть списки подписчиков внутри магазинов.

И это действительно тот же принцип в Redux, где у вас есть один магазин, в то время как в Flux у вас может быть несколько магазинов.

Теперь небольшая математика. Имея 2 компонента A и B, вам нужно иметь только несколько возможных цепей обновления. Обновления B и B обновляются A или самообновление (без включения здесь обновлений извне приложения). Это возможный случай.

введите описание изображения здесь

Только с тремя компонентами мы имеем гораздо более возможные цепи.

введите описание изображения здесь

И с еще большим количеством компонентов он становится сложным. Таким образом, чтобы подавить экспоненциальную сложность взаимодействия возможных компонентов, мы имеем этот шаблон потока, который не более чем IDispatch, IObservable, если вы работали с этими интерфейсами с некоторых других языков программирования. Один из них был бы для плющения действий, а другой для входа в цепочку слушателей, которая существует внутри хранилища.

С помощью этого шаблона ваш код React будет организован иначе, чем обычный подход React. Вам больше не придется использовать состояние React.Component. Вместо этого вы будете использовать Store (s), которые будут содержать состояние приложения.

В вашем компоненте может отображаться только желание изменить состояние приложения путем отправки действия. Например: onClick может отправить действие, чтобы увеличить счетчик. Эти действия являются объектами с свойством type:, который обычно является строкой, и обычно в верхнем регистре, но объект действия может иметь много других реквизитов, таких как ID, значение,...

Поскольку компоненты отвечают за рендеринг на основе состояния приложения, нам нужно как-то доставить им состояние приложения. Это может быть через props = store.getState(), или мы можем использовать context. Но также проверьте это.

Наконец, даже не запрещено, чтобы компонент использовал внутреннее состояние (this.state), если это не влияет на приложение. Вы должны признать эти случаи.