Reputation: 1396
I have a HOC, currently i wanna revamp it to Hook version, however i found that it always render
let see the example:
const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
const HOC = ({...props}) => {
const [selected, setSelected] = useState(f());
return <WrappedComponent {...props} setSelected={setSelected}/>
}
return HOC;
}
f() will always call when setSelected trigger from WrappedComponent
let see the other example:
const f = ()=> { console.log("init"); return "";}
const hoc = ({someProp = ""}) => WrappedComponent => {
class HOC extends Component {
constructor(props) {
super(props);
this.state = {selected: f()}
this.setSelected = this.setSelected.bind(this);
}
setSelected(value) {
this.setState({selected:value})
}
render() {
return <WrappedComponent {...props} setSelected={this.setSelected}/>
}
}
return HOC;
}
f() will only call once
How do i solve this case if i must use Hoc Format, but just wanna hoc itself become a functional component?
or i just change
const [selected, setSelected] = useState(f());
to
const [selected, setSelected] = useState(() => f());
Upvotes: 1
Views: 162
Reputation: 1396
the answer is change
const [selected, setSelected] = useState(f());
to
const [selected, setSelected] = useState(() => f());
and f() will only call once no matter how many time it render, except unmount
Upvotes: 0
Reputation: 2784
You are misusing the useState
.
Every time the HOC render, f()
will be called.
Let me verbose here, maybe the following code would make you see more clearly
const hoc = ({someProp = ""}) => WrappedComponent => {
const HOC = ({...props}) => {
const state = f(); // Sure, this line would be executed every time.
const [selected, setSelected] = useState(state);
...
}
...
}
I guess that you want to execute f()
to get init state when initializing Component and then let the Component handle the state itself, although it is not recommended.
For this scenario, I would prefer one of the following approaches:
Pass the result of f()
from parent to HOC component
This is the simplest way that create HOC and generate init state at same time
use useEffect
if the first time rendering with blank state is fine.
You can think
useEffect
as olddidMount
lifecycle API.
Upvotes: 1