Некоторые из моих компонентов должны быть отрисованы только один раз, так как тогда я просто хочу, чтобы они прослушивали изменения в глобальном хранилище и действовали соответственно. Но я не могу это сделать: store.subscribe и redux-watch, которые я пробовал, срабатывали только тогда, когда данные были отправлены, но не тогда, когда хранилище фактически изменилось, что означает, что соответствующая функция не может использовать this.props.bla, потому что он не обновлен еще. Есть ли какое-то решение, позволяющее узнать, когда this.props.bla действительно изменилось, без использования bla в функции рендеринга?
Пример компонента:
import React, { Component } from 'react';
import { connect } from 'react-redux';
const mapStateToProps = state => {
return {
position: state.position //<== when to know for sure it changed?
};
};
class MyComp extends Component {
constructor(props) {
super(props);
this.state = {
number: 0
};
store.subscribe(() => {
const currentState = store.getState();
// even if I have the updated value here in currentState, there are not guarantees this.props.position already changed.
});
}
calculate = ()=>{
// Do some calculation with this.props.position and change the number.
}
render(){
return <div>{this.state.number}</div>;
}
}
export default connect(mapStateToProps)(MyComp);
Извините, но Redux - это такая боль .... Только что перешел на React Query, и мне это нравится. Я могу буквально перейти на страницу, показывающую 4 записи базы данных, перейти к моему инструменту базы данных и удалить запись, а затем, когда я снова нажму на окно браузера, оно обновится. Вы также можете отменить любые существующие запросы, заставив React Query снова получить данные.
@DrewReese Я уже использую соединение, но я не знаю, как прослушивать изменения, если я не добавляю реквизиты в функцию рендеринга. Можете ли вы привести пример такого компонента (может быть, вы создадите ответ?) Спасибо!
@TonyDrummond Спасибо за совет! Я тоже думаю использовать что-то другое. Позволяет ли Reac Query иметь центральное хранилище, такое как хранилище избыточности. Мне нужно несколько компонентов, чтобы использовать какой-то глобальный источник.
@mimic - я только что сделал это видео для кого-то сегодня, который кратко просматривает его. Я новый разработчик (3 месяца опыта работы со стеком MERN) и смог преобразовать все свое приложение, исключив 1500 строк действий Redux, констант, редьюсеров и других BS. Вот: youtu.be/rb7ZDj-0NWU
Возможно, я не совсем понимаю, о чем вы думаете. Когда хранилище избыточности обновляется, все подписанные компоненты получают новый объект хранилища/состояния. Когда сопоставленные реквизиты (или контекст избыточности) обновляются, компонент перерисовывается с обновленным значением хранилища/состояния избыточности. Я мог бы попытаться дать ответ, но это может оказаться трудным, если мы на самом деле не знаем, в чем заключается ваша проблема и что делает ваш код. Не могли бы вы предоставить минимальный, полный и воспроизводимый пример вашего кода?
@TonyDrummond Redux (и, соответственно, react-redux) в порядке, хотя и немного многословен. Если шаблонность старого react-redux для вас слишком велика, я предлагаю вам проверить redux-toolkit от той же команды, которая принесла вам react-redux. По сути, это еще один уровень абстракции по сравнению с react-redux, который обрабатывает «шаблонный» код за вас. Кроме того, он инкапсулирует логику редуктора, поэтому вам не нужно беспокоиться об изменчивости состояния.
@DrewReese Проблема в том, что я не хочу использовать функцию рендеринга для обновления значений из хранилища. Поэтому мне нужно найти способ узнать об изменениях, но без повторного рендеринга компонента.
Я все еще не понимаю, функция render
должна быть чистой функцией без побочных эффектов, она не должна ничего обновлять. Если вы имеете в виду тело функции функционального компонента, опять же, это должна быть чистая функция без побочных эффектов. Возможно, если вы покажете, что вы пытаетесь сделать, будет яснее, чего вы хотите.
@DrewReese спасибо, но после использования React Query я никогда не вернусь к Redux :). Запрос React обрабатывает весь магазин — мне не пришлось ничего настраивать.
Вы читали редукс-документы для магазина , подписывайтесь . «Добавляет прослушиватель изменений. Он будет вызываться каждый раз, когда отправляется действие, и некоторая часть дерева состояний потенциально может измениться. Затем вы можете вызвать getState()
, чтобы прочитать текущее дерево состояний внутри обратного вызова». Вы пытались получить текущее состояние в обратном вызове?
@DrewReese Я не спрашиваю, как увидеть значение внутри обратного вызова. Мне нужен надежный способ прочитать изменения ПОСЛЕ их выполнения, а не в обратном вызове. Рабочий процесс таков: 1) вносятся изменения в хранилище 2) компонент знает об этом и 3) вызывает соответствующую функцию 4) которая считывает измененные данные из хранилища. Функция рендеринга имеет прямое действие — она перерисовывает мой компонент. У компонента есть функция рендеринга, но он работает в основном с другими данными, которые не помещаются в функцию рендеринга. Что мне нужно, так это надежный способ узнать об изменениях, сделанных в магазине.
@DrewReese Я добавил пример компонента.
Итак, вы просто хотите знать, когда обновляется значение state.position
/props.position
? Внедрите componentDidUpdate
метод жизненного цикла, сравните prevProps.position !== this.props.position
и сделайте то, что вам нужно.
@DrewReese, вы правы, я просто хочу знать, когда this.props.value изменилось, позвольте мне попробовать это решение.
@DrewReese Это сработало!! Не могли бы вы добавить свой комментарий в качестве ответа, я отмечу его как решение. Спасибо!
Если вы хотите «отреагировать» на конкретное обновление значения реквизита, вам следует реализовать метод жизненного цикла componentDidUpdate
. В вашем случае, если вам нужно знать, когда обновилось введенное значение реквизита position
, добавьте условие для сравнения предыдущего значения реквизита position
с текущим значением реквизита position
.
componentDidUpdate(prevProps) {
if (prevProps.position !== this.props.position) {
// position value updated!
}
}
У меня есть другая проблема - по какой-то причине, когда значение хранилища избыточности изменяется, мой render() вызывается, но не componentDidUpdate(), и я не могу понять, почему. Есть идеи? Спасибо!
@mimic Я не могу представить себе сценарий, в котором render
можно было бы вызвать при обновлении DOM и каким-то образом componentDidUpdate
не вызвать. Не стесняйтесь задавать новый вопрос о SO и пинговать меня здесь со ссылкой на него, я могу взглянуть, когда у меня будет минутка. Как минимум, он будет более заметен, и вы сможете быстрее привлечь к нему внимание.
Спасибо, Дрю! На самом деле я обнаружил, что монтирую компонент вместо его обновления, ха-ха, поэтому он не вызывался, а был вызван componentDidMount() :)
Вы можете подписаться на изменения в магазине Redux, подписавшись на магазин. Не используйте
store.subscribe
напрямую. Используйте connect HOC или useSelector реакцию, чтобы подключиться к прослушиванию конкретных изменений.