TkDodo / blog-comments

6 stars 1 forks source link

blog/use-state-vs-use-reducer #30

Closed utterances-bot closed 2 years ago

utterances-bot commented 3 years ago

TkDodo's blog

A technical blog about frontend-development, TypeScript and React

https://tkdodo.eu/blog/use-state-vs-use-reducer

svirmi commented 3 years ago

Thanks! Very good reading!

morijenab commented 3 years ago

const [state, dispatch] = React.useReducer(reducer(data)) can we apply lazy initial here as well? I don't know! just wondering the same concept can be apply here or not ?

TkDodo commented 3 years ago

can we apply lazy initial here as well?

sure, I left out the initializer because the actual reducer state is independent. You can still do:

React.useReducer(reducer(data), () => computeMyInitialState())

JulesBlm commented 3 years ago

Really good article, as are the rest in this series, well the whole blog really.

Another good use of an object in useState I came across is 'camera state' for SVG viewBox in this great blogpost on making a zoom ui by Steve Ruiz. When the camera is zoomed or panned, x and y change together, so it makes sense to bundle it into one.

On this comment

sure, I left out the initializer because the actual reducer state is independent. You can still do: React.useReducer(reducer(data), () => computeMyInitialState())

Actually, useReducer lazy init is slightly different from that of useState. useReducer accepts a lazy initializer function as its third parameter which uses the second parameter to useReducer as its argument (React docs). This may sound vague so let just look at code instead

const reducer =  (amount) => (state, action) => { ... }

// Let's pretend this is actually a hefty calculation
const computeInitialState = (value) => value ** 2;

const initialValue = 10

export default function App() {

  const [count, dispatch] = useReducer(
    reducer,
    initialValue,
    computeMyInitialState // 'computeInitialState' is called only on init with 'initialValue' which is 10
  );

Or see this CodeSandbox I whipped together quickly.

TkDodo commented 3 years ago

@JulesBlm Thank you for the kind words 🙏

When the camera is zoomed or panned, x and y change together, so it makes sense to bundle it into one.

Definitely another good one 👍

Actually, useReducer lazy init is slightly different from that of useState

You are of course totally right about that, thanks for pointing it out. I guess if you just want a function to initialize that runs once, without a value, you'd need to do:

React.useReducer(reducer(data), undefined, () => computeMyInitialState())