Как прослушивать изменения состояния в react.js?

153

Что эквивалентно функции angular $ watch в React.js?

Я хочу прослушивать изменения состояния и вызывать такую ​​функцию, как getSearchResults ().

componentDidMount: function() {
    this.getSearchResults();
}
Эниз Гюлек
источник

Ответы:

38

Я не использовал Angular, но, читая ссылку выше, кажется, что вы пытаетесь кодировать что-то, что вам не нужно обрабатывать. Вы вносите изменения в состояние в иерархии компонентов React (через this.setState ()), и React заставляет ваш компонент повторно визуализироваться (фактически «прослушивая» изменения). Если вы хотите «слушать» другой компонент в вашей иерархии, у вас есть два варианта:

  1. Передайте обработчики вниз (через реквизиты) от общего родителя и попросите их обновить состояние родителя, в результате чего иерархия ниже родителя будет повторно отрисована.
  2. В качестве альтернативы, чтобы избежать резкого увеличения количества обработчиков, каскадно спускающихся по иерархии, вы должны взглянуть на шаблон потока , который перемещает ваше состояние в хранилища данных и позволяет компонентам отслеживать их изменения. Плагин Fluxxor очень полезен для управления этим.
Edoloughlin
источник
4
Но как насчет того, когда вам нужно получить удаленные данные, которые используют (часть) состояние в качестве параметра url / a?
RnMss
@RnMss - посмотрите на redux и redux ( redux.js.org/docs/basics/Reducers.html ), а также повторно выберите ( github.com/reactjs/reselect ).
edoloughlin
329

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

componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
Дерек Слэджер
источник
6
Требовалось запустить метод, когда свойство в другом компоненте было обновлено (вверх на одно через обратный вызов, на одно вниз через опору), и добавление componentDidUpdateкомпонента с опорой было правильным рецептом. Спасибо за это.
Keith DC
Я думаю, что это лучший способ гарантировать уведомление об изменениях состояния, о чем просил OP. Но обратите внимание, что ни один из этих методов не сработает после изменения состояния, если вы наложите вето на обновление в shouldComponentUpdate.
MidnightJava
31
componentWillUpdateустарел: reactjs.org/blog/2018/03/27/update-on-async-rendering.html
Дмитрий Минковский
1
componentDidUpdateне будет также срабатывать при получении новых свойств, не обязательно только при изменении состояния?
Энди Маккалоу
2
componentWillUpdateне рекомендуется.
Шон
29

Я думаю, вам следует использовать ниже Жизненный цикл компонента, как если бы у вас есть свойство ввода, которое при обновлении должно запускать обновление вашего компонента, тогда это лучшее место для этого, поскольку оно будет вызываться перед рендерингом, вы даже можете обновить состояние компонента, чтобы оно было отражается на представлении.

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}
хасайн
источник
6
componentWillReceiveProps устарел: responsejs.org/docs/…
Джон Скумбурдис
18

Начиная с React 16.8 в 2019 году с хуками useState и useEffect , следующее теперь эквивалентно (в простых случаях):

AngularJS:

$scope.name = 'misko'
$scope.$watch('name', getSearchResults)

<input ng-model="name" />

Реагировать:

const [name, setName] = useState('misko')
useEffect(getSearchResults, [name])

<input value={name} onChange={e => setName(e.target.value)} />
Априллион
источник
2

Использование useState с useEffect, как описано выше, является абсолютно правильным способом. Но если функция getSearchResults возвращает подписку, то useEffect должен вернуть функцию, которая будет отвечать за отказ от подписки. Функция, возвращенная из useEffect, будет запускаться перед каждым изменением зависимости (имя в приведенном выше случае) и при уничтожении компонента.

Шиванг Гупта
источник
1

Это было давно, но на будущее: можно использовать метод shouldComponentUpdate ().

Обновление может быть вызвано изменениями свойств или состояния. Эти методы вызываются в следующем порядке при повторной визуализации компонента:

static getDerivedStateFromProps() 
shouldComponentUpdate() 
render()
getSnapshotBeforeUpdate() 
componentDidUpdate()

ссылка: https://reactjs.org/docs/react-component.html

Мальвинка
источник
Вам нужно будет вернуть логическое значение from, shouldComponentUpdateпоэтому оно может не подходить для этого варианта использования.
Шон
0

В 2020 году вы можете прослушивать изменения состояния с помощью хука useEffect следующим образом

export function MyComponent(props) {
    const [myState, setMystate] = useState('initialState')

    useEffect(() => {
        console.log(myState, '- Has changed')
    },[myState]) // <-- here put the parameter to listen
}
Владимир Вс
источник