在React.js中,与Angular的$watch函数相当的是什么?
我想监听状态变化并调用像getSearchResults()这样的函数。
我想监听状态变化并调用像getSearchResults()这样的函数。
componentDidMount: function() {
this.getSearchResults();
}
componentDidMount: function() {
this.getSearchResults();
}
当状态改变时,以下生命周期方法将被调用。您可以使用提供的参数和当前状态来确定是否发生了有意义的更改。
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
export function MyComponent(props) {
const [myState, setMyState] = useState('initialState')
useEffect(() => {
console.log(myState, '- Has changed')
},[myState]) // <-- here put the parameter to listen, react will re-render component when your state will be changed
}
useEffect
的这种用法本身总是会导致额外的渲染 - 有没有什么方法可以避免这种情况? - PhilzenuseEffect
的第二个参数传递进去(例如上面的例子中的 [myState]),那么只有在依赖数组中的变量发生改变时,组件才会重新渲染。 - Ryan Schafercount
从20
变为21
),并在其发生变化时运行一些代码。 useEffect
在React hooks中实现了这一点。不确定在React hooks之前机制是什么,或者是否存在这样的机制。 - Marius自2019年React 16.8推出 useState 和 useEffect Hooks后,在简单情况下,以下几个框架现在是等价的:
AngularJS:
$scope.name = 'misko'
$scope.$watch('name', getSearchResults)
<input ng-model="name" />
React:
const [name, setName] = useState('misko')
useEffect(getSearchResults, [name])
<input value={name} onChange={e => setName(e.target.value)} />
我认为你应该使用下面的组件生命周期。如果你有一个输入属性,需要在更新时触发组件更新,那么这是最好的位置,因为它将在渲染之前被调用,你甚至可以更新组件状态以反映在视图中。
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
如果你使用钩子(hooks)像是const [ name , setName ] = useState ('')
,你可以尝试以下内容:
useEffect(() => {
console.log('Listening: ', name);
}, [name]);
使用上述描述的useEffect和useState是绝对正确的方式。但是,如果getSearchResults函数返回订阅,则useEffect应该返回一个函数,负责取消订阅。从useEffect返回的函数将在每次更改依赖项(在上面的例子中是name)之前运行,并在组件销毁时运行。
有一段时间没有更新了,但是作为以后的参考:可以使用方法shouldComponentUpdate()。
更改props或state会导致更新。当组件重新渲染时,这些方法按以下顺序调用:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
React组件是构建React应用程序的基本单元。每个组件都有自己的状态和生命周期方法,可以在组件内部进行处理。当组件的props或state发生变化时,React会自动重新渲染组件。您可以使用React.Component类来定义组件,并覆盖其生命周期方法以执行特定操作。
shouldComponentUpdate
返回一个布尔值,因此它可能不适合这种情况。 - sean我使用这段代码来查看依赖项中的哪个发生了变化。在许多情况下,这比纯粹的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 ]);
componentDidUpdate
添加到拥有该属性的组件中是正确的解决方案。感谢您提供这个方法。 - Keith DCcomponentWillUpdate
正在被废弃:https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html - Dmitry MinkovskycomponentDidUpdate
是否也会触发,而不仅仅是在状态改变时? - andy mcculloughcomponentWillUpdate
已被弃用。 - sean