Do you want to request a feature or report a bug?
feature.
// index.js
state = {num: 0 }
componentDidMount() {
const numGenerator = () => Math.floor(Math.random()*10)
setInterval(() => this.setState({num: numGenerator()}) , 1000 )
}
render(){
return <Display num={this.state.num} />
}
Say 5,4,1,7 ... passed into <Display />
, I want the component to display:
5, haha, 4, haha, 1, haha, 7 ,haha, ... (and I want haha to show just in a flash)
//Display.js
state = { showHaha: false }
componentWillReceiveProps(){
if ...
this.setState({ showHaha: true })
}
componentDidUpdate() {
if ...
this.setState({ showHaha: false })
}
But setState inside componentDidUpdate is bad practice, right? So what should I do?
And can we have a 'watch' method like in Vue.js?
I wouldn't be using the React lifecycle at all for this (nor relying on the period of time between lifecycle methods to flash up text). It's entirely a problem of state - "what should I show, for how long, and what is next?"
Example (in ES2017 for brevity):
componentDidMount() {
this.cycleState();
}
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function cycleState() {
for (const num of this.props.nums) {
this.setState({text: num});
await delay(1000);
this.setState({text: 'haha'});
await delay(10);
}
}
(This isn't a flawless solution - it doesn't support changing props, handling dismount, etc.)
I'm struggling to understand what exactly you want.
For questions about React, I encourage you to check out community support resources:
https://reactjs.org/community/support.html
setState()
inside componentWillReceiveProps()
will only produce one re-render. This is intentional. It’s not clear to me why (and whether) you’d want two renders instead. A more practical example would probably help.
@gaearon
I took sometime make this codesandbox demo to illustrate what I mean.
Yesterday I was coding complex js animation into React project, and finding "watcher" will be helpful in so many cases.
Why I want watcher?
watch: {
someState(oldValue,newValue){
doSomething
}
}
this is vue watcher. I love React more, but two things that I think vue does better is watcher and animation.
Essentially, react automates the headache part of work "when state changes, UI changes accordingly"(it is kind of a watcher). Inevitablly, there are cases that when state changes, we want to do more than simple UI rerender. To me, it's very natural that React could take care of that in a same elegant manner (by watcher).
I understand life cycle can sort of nail it, but this twitts really makes me feel more confusing in life cycle than ever. In my React projects, apart from loading data from backend, 99% of the use case of life cycle is to "watch a certain state or props, when it changes do something". That's exactly a watcher. And to be honest watcher helps me coding clearly of what I think, rather than worrying which one or two life cycle(s) should I write this code in.
P.S. If possible, I'd really love you suggestion on this. Thank you so much.
So, in React you use componentDidUpdate
for this.
componentDidUpdate(prevProps, prevState) {
// ...
}
You can compare this.props
with prevProps
in it, and this.state
with prevState
and do anything you like.
I don’t agree with you that having a separate “watcher” declaration for a specific value is better:
“Watchers” have to be created for individual values. But what if your logic is more complex? For example if you want to fire off a single side effect when either of two values change? If you created two watchers then you’d have to deduplicate requests later. Similarly, you might need to have access to current and previous values of all properties (not just one) to determine what to do. So eventually you need something like componentDidUpdate
anyway. At least React gives you that immediately instead of leaving you to scratch your head later when your requirements don’t match the limited API.
Your suggested API isn’t friendly to static typing. With TypeScript or Flow, you can easily type props and state once, and have right types throughout the component including lifecycle methods. With the “watcher” API you proposed, you’d have to manually type the individual watcher methods and make sure they don’t diverge from the props/state type definitions.
You don't need to create two watchers when you need more complex, in Vue you can use computed
if you "want to fire off a single side effect when either of two values change".
If you’d like to propose a new React API please do so here: https://github.com/reactjs/rfcs
Thank you!
Most helpful comment
You don't need to create two watchers when you need more complex, in Vue you can use
computed
if you "want to fire off a single side effect when either of two values change".