如何在react.js中监听状态变化?

angular的$函数在React.js中等价于什么?

我想侦听状态变化并调用类似getSearchResults()的函数。

componentDidMount: function() {
this.getSearchResults();
}
373633 次浏览

下面的生命周期方法将在状态改变时被调用。您可以使用提供的参数和当前状态来确定是否发生了有意义的更改。

componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
我还没有用过Angular,但是看了上面的链接,看起来你在为一些你不需要处理的东西编写代码。你改变了React组件层次结构中的状态(通过this.setState()), React会导致你的组件被重新渲染(有效地“监听”变化)。 如果你想从层次结构中的另一个组件“监听”,那么你有两个选项:

  1. 从一个公共的父对象向下传递处理程序(通过props),并让它们更新父对象的状态,导致父对象下面的层次结构被重新呈现。
  2. 或者,为了避免处理程序在层次结构中层叠而下的爆炸,您应该查看通量模式,它将您的状态移动到数据存储中,并允许组件监视它们的变化。Fluxxor插件对于管理这个非常有用。

我认为你应该使用下面的组件生命周期,如果你有一个输入属性,在更新时需要触发你的组件更新,那么这是最好的地方,因为它将在呈现之前被调用,你甚至可以更新组件状态以反映在视图上。

componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}

已经有一段时间了,但为了将来参考:可以使用shouldComponentUpdate()方法。

一个更新可以由道具或状态的变化引起。这些方法 在组件被调用时,以以下顺序调用 单元格:< / p >

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

裁判:https://reactjs.org/docs/react-component.html

自2019年React 16.8推出useStateuseEffect钩子以来,以下钩子现在是等效的(在简单情况下):

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)} />

如上所述,使用useState和useEffect是绝对正确的方法。但是如果getSearchResults函数返回订阅,那么useEffect应该返回一个负责取消订阅的函数。useEffect返回的函数将在每次更改依赖项(上面的名称)之前和组件销毁时运行

在2020年,你可以像这样用useEffect钩子监听状态变化

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


useEffect(() => {
console.log(myState, '- Has changed')
},[myState]) // <-- here put the parameter to listen
}

如果你使用像const [name, setName] = useState(' ')这样的钩子,你可以尝试以下方法:

 useEffect(() => {
console.log('Listening: ', name);
}, [name]);

我使用这段代码来查看依赖关系中的哪一个发生了变化。在许多情况下,这比纯useEffect更好。

// useWatch.js
import { useEffect, useMemo, useRef } from 'react';


export function useWatchStateChange(callback, dependencies) {
const initialRefVal = useMemo(() => dependencies.map(() => null), []);
const refs = useRef(initialRefVal);
useEffect(() => {
for(let [index, dep] of dependencies.entries()) {
dep = typeof(dep) === 'object' ? JSON.stringify(dep) : dep;
const ref = refs.current[index];
if(ref !== dep) {
callback(index, ref, dep);
refs.current[index] = dep;
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, dependencies);
}

在React组件中

// App.js
import { useWatchStateChange } from 'useWatch';
...
useWatchStateChange((depIndex, prevVal, currentVal) => {
if(depIndex !== 1) { return } // only focus on dep2 changes
doSomething("dep2 now changes", dep1+dep2+dep3);
}, [ dep1, dep2, dep3 ]);