How to listen state changes in react.js?
JavascriptReactjsJavascript Problem Overview
What is the angular's $watch function equivalent in React.js?
I want to listen state changes and call a function like getSearchResults().
componentDidMount: function() {
this.getSearchResults();
}
Javascript Solutions
Solution 1 - Javascript
The following lifecycle methods will be called when state changes. You can use the provided arguments and the current state to determine if something meaningful changed.
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
Solution 2 - Javascript
In 2020 you can listen state changes with useEffect hook like this
export function MyComponent(props) {
const [myState, setMystate] = useState('initialState')
useEffect(() => {
console.log(myState, '- Has changed')
},[myState]) // <-- here put the parameter to listen
}
Solution 3 - Javascript
I haven't used Angular, but reading the link above, it seems that you're trying to code for something that you don't need to handle. You make changes to state in your React component hierarchy (via this.setState()) and React will cause your component to be re-rendered (effectively 'listening' for changes). If you want to 'listen' from another component in your hierarchy then you have two options:
- Pass handlers down (via props) from a common parent and have them update the parent's state, causing the hierarchy below the parent to be re-rendered.
- Alternatively, to avoid an explosion of handlers cascading down the hierarchy, you should look at the flux pattern, which moves your state into data stores and allows components to watch them for changes. The Fluxxor plugin is very useful for managing this.
Solution 4 - Javascript
Since React 16.8 in 2019 with useState and useEffect Hooks, following are now equivalent (in simple cases):
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)} />
Solution 5 - Javascript
I think you should be using below Component Lifecycle as if you have an input property which on update needs to trigger your component update then this is the best place to do it as its will be called before render you even can do update component state to be reflected on the view.
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
Solution 6 - Javascript
If you use hooks like const [ name , setName ] = useState (' '), you can try the following:
useEffect(() => {
console.log('Listening: ', name);
}, [name]);
Solution 7 - Javascript
Using useState with useEffect as described above is absolutely correct way. But if getSearchResults function returns subscription then useEffect should return a function which will be responsible for unsubscribing the subscription . Returned function from useEffect will run before each change to dependency(name in above case) and on component destroy
Solution 8 - Javascript
It's been a while but for future reference: the method shouldComponentUpdate() can be used.
> An update can be caused by changes to props or state. These methods > are called in the following order when a component is being > re-rendered: >
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()