Reputation: 47
I am trying to figure out re-writing "even number counter" example below, by only using functional components instead of class method.
Here is the original one:
Code
class ShouldComponentUpdate extends React.Component {
constructor (props) {
super(props)
this.state = {
value: 0
}
this.addValue = this.addValue.bind(this)
}
addValue () {
this.setState((state) => ({
value: state.value + 1
}))
}
render () {
return (
<div>
<button onClick={this.addValue}>Add</button>
<OnlyEvens value={this.state.value} />
</div>
)
}
}
class OnlyEvens extends React.Component {
constructor (props) {
super(props)
}
shouldComponentUpdate (nextProps, nextState) {
if (nextProps.value % 2 === 0) return true
}
render () {
return (
<div>
<h1>{this.props.value}</h1>
</div>
)
}
}
Well, I try to do something below but I lost in callback function. Can someone review please?
Code
function ComponentShouldUpdate () {
const [counter, setCounter] = useState(0)
return (
<div>
<button onClick={() => setCounter(counter + 1)}>Add</button>
<EvenCounter counter={counter} />
</div>
)
}
const EvenCounter = React.memo(({ counter }) => {
function checkEven (nextProps, nextState) {
if (nextProps.counter % 2 === 0) {
//lost in here
}
}
return (
<div>
<h2>{counter}</h2>
</div>
)
})
Upvotes: 2
Views: 845
Reputation: 81400
You should separate the counter logic into your own custom hook something like useEvenCounter
. Because hooks are composable, it can be reused anywhere else, not just in your particular component
function useEvenCounter(initialValue: number = 0) {
const [value, setValue] = React.useState(initialValue);
const increment = React.useCallback(
() => setValue((v) => (v % 2 === 0 ? v + 2 : v + 1)),
[]
);
return [value, increment] as const;
}
export default function App() {
const [value, increment] = useEvenCounter();
const [value2, increment2] = useEvenCounter(1);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={() => increment()}>+</button>
<div>{value}</div>
<button onClick={() => increment2()}>+</button>
<div>{value2}</div>
</div>
);
}
You can play around in the live demo below. Hit me up if you don't understand anything
Upvotes: 1