Подтвердить что ты не робот

Подпишитесь на одно изменение недвижимости в магазине Redux

В Redux я могу легко подписаться на сохранение изменений с помощью

store.subscribe(() => my handler goes here)

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

4b9b3361

Ответ 1

Невозможно подписаться на часть магазина при непосредственном использовании subscribe, но, как говорит сам создатель Redux - не использовать subscribe прямо! Для того, чтобы поток данных приложения Redux действительно работал, вам понадобится один компонент, который обертывает ваше приложение. Этот компонент будет подписаться на ваш магазин. Остальные компоненты будут дочерними элементами этого компонента-обертки и получат только те части состояния, в которых они нуждаются.

Если вы используете Redux с React, тогда есть хорошие новости - официальный пакет react-redux позаботится об этом для вас! Он предоставляет этот компонент оболочки, называемый <Provider />. Затем у вас будет хотя бы один "умный компонент", который прослушивает изменения состояния, переданные Provider из хранилища. Вы можете указать, какие части состояния он должен прослушивать, и те части состояния будут переданы в виде реквизита для этого компонента (и, конечно же, это может передать их собственным детям). Вы можете указать это, используя функцию connect() на вашем "умном" компоненте и используя функцию mapStateToProps в качестве первого параметра. Напомним:

Заменить корневой компонент с компонентом Provider, который подписывается на сохранение изменений

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Теперь любой дочерний элемент <App />, который завернут с помощью connect(), будет "умным" компонентом. Вы можете пройти в mapStateToProps, чтобы выбрать определенные части состояния и передать их в качестве реквизита.

const mapStateToProps = (state) => {
    return {
        somethingFromStore: state.somethingFromStore
    }
}

class ChildOfApp extends Component {
    render() {
        return <div>{this.props.somethingFromStore}</div>
    }
}

//wrap App in connect and pass in mapStateToProps
export default connect(mapStateToProps)(ChildOfApp)

Очевидно, что <App /> может иметь много детей, и вы можете выбрать, какие части состояния mapStateToProps должны прослушивать для каждого из своих детей. Я бы предложил прочитать документы использование с React, чтобы лучше понять этот поток.

Ответ 2

Redux предлагает только один общий способ узнать, когда хранилище обновлено: метод subscribe. Обратные вызовы на subscribe не получают никакой информации о том, что могло измениться, поскольку API subscribe преднамеренно низкоуровневый и просто запускает каждый обратный вызов без аргументов. Все, что вы знаете, это то, что магазин каким-то образом обновился.

Из-за этого кто-то должен написать конкретную логику сравнения старого состояния с новым состоянием и посмотреть, изменилось ли что-то. Вы можете справиться с этим, используя React-Redux, указав функцию mapStateToProps для вашего компонента, внедряя componentWillReceiveProps в свой компонент и проверяя, изменились ли определенные реквизиты из хранилища.

Есть также несколько аддон-библиотек, которые пытаются обработать этот случай: https://github.com/ashaffer/redux-subscribe и https://github.com/jprichardson/redux-watch. Оба в основном позволяют указать конкретную часть состояния, на которое нужно смотреть, используя разные подходы.

Ответ 3

В дополнение к тому, что сказал Энди Ноэлкер, mapStateToProps не только передает часть состояния должным образом по вашему дереву компонентов, он также подписывается на изменения, внесенные непосредственно в эти подписанные части состояния.

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

Если вы хотите уменьшить данные из состояния при подписке, например, у вас есть данные списка в состоянии, и вы хотите преобразовать его в объект с помощью идентификаторов как ключей или хотите присоединиться к нескольким состояниям в структурах данных, вы должен объединять mapStateToProps с библиотекой createSelector из reselect, делая все эти изменения внутри селектора. Селекторы - это чистые функции, которые уменьшают и кэшируют состояния, переданные в качестве входных данных, и если ввод не изменился - они возвращают точно такую ​​же ссылку, что и при последнем вызове, - без выполнения сокращения.

Ответ 4

Я лучше следую этой теме, чтобы получить новости, потому что мне это нужно.

До сих пор я думаю: Текущее состояние и предыдущее состояние можно использовать как 2 json-объект. Сравнение различий между двумя JSON может помочь нам узнать фактическое изменение.

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