[{"data":1,"prerenderedAt":266},["ShallowReactive",2],{"blog-en-react-hooks-change-everything":3},{"id":4,"title":5,"body":6,"cover":251,"date":252,"description":253,"draft":254,"extension":255,"locale":256,"meta":257,"navigation":125,"path":258,"seo":259,"stem":260,"tags":261,"__hash__":265},"blog\u002Fblog\u002Fen\u002Freact-hooks-change-everything.md","How React Hooks changed everything",{"type":7,"value":8,"toc":247},"minimark",[9,22,27,41,47,50,211,214,218,231,234,240,243],[10,11,12,13,17,18,21],"p",{},"When React 16.8 shipped Hooks back in February, I'll admit I was skeptical. Class components were my daily reality, and I had learned to live with their quirks. But after a few days with ",[14,15,16],"code",{},"useState"," and ",[14,19,20],{},"useEffect",", it was clear: this isn't a new feature. It's a new way of thinking.",[23,24,26],"h2",{"id":25},"less-scaffolding-more-logic","Less scaffolding, more logic",[10,28,29,30,33,34,17,37,40],{},"What surprised me most was how much ballast suddenly disappeared. No more ",[14,31,32],{},"this",", no binding in the constructor, no logic scattered across ",[14,35,36],{},"componentDidMount",[14,38,39],{},"componentWillUnmount"," that really belonged together. With Hooks, related logic finally lives together too.",[42,43,44],"blockquote",{},[10,45,46],{},"A component should read like a clear thought, not like a transcript of lifecycle events.",[10,48,49],{},"An example from my everyday work:",[51,52,57],"pre",{"className":53,"code":54,"language":55,"meta":56,"style":56},"language-jsx shiki shiki-themes github-light github-dark","function ProfileCard({ userId }) {\n  const [user, setUser] = useState(null);\n\n  useEffect(() => {\n    fetchUser(userId).then(setUser);\n  }, [userId]);\n\n  return user ? \u003CCard data={user} \u002F> : \u003CSpinner \u002F>;\n}\n","jsx","",[14,58,59,83,120,127,142,157,163,168,205],{"__ignoreMap":56},[60,61,64,68,72,76,80],"span",{"class":62,"line":63},"line",1,[60,65,67],{"class":66},"szBVR","function",[60,69,71],{"class":70},"sScJk"," ProfileCard",[60,73,75],{"class":74},"sVt8B","({ ",[60,77,79],{"class":78},"s4XuR","userId",[60,81,82],{"class":74}," }) {\n",[60,84,86,89,92,96,99,102,105,108,111,114,117],{"class":62,"line":85},2,[60,87,88],{"class":66},"  const",[60,90,91],{"class":74}," [",[60,93,95],{"class":94},"sj4cs","user",[60,97,98],{"class":74},", ",[60,100,101],{"class":94},"setUser",[60,103,104],{"class":74},"] ",[60,106,107],{"class":66},"=",[60,109,110],{"class":70}," useState",[60,112,113],{"class":74},"(",[60,115,116],{"class":94},"null",[60,118,119],{"class":74},");\n",[60,121,123],{"class":62,"line":122},3,[60,124,126],{"emptyLinePlaceholder":125},true,"\n",[60,128,130,133,136,139],{"class":62,"line":129},4,[60,131,132],{"class":70},"  useEffect",[60,134,135],{"class":74},"(() ",[60,137,138],{"class":66},"=>",[60,140,141],{"class":74}," {\n",[60,143,145,148,151,154],{"class":62,"line":144},5,[60,146,147],{"class":70},"    fetchUser",[60,149,150],{"class":74},"(userId).",[60,152,153],{"class":70},"then",[60,155,156],{"class":74},"(setUser);\n",[60,158,160],{"class":62,"line":159},6,[60,161,162],{"class":74},"  }, [userId]);\n",[60,164,166],{"class":62,"line":165},7,[60,167,126],{"emptyLinePlaceholder":125},[60,169,171,174,177,180,183,186,189,191,194,197,199,202],{"class":62,"line":170},8,[60,172,173],{"class":66},"  return",[60,175,176],{"class":74}," user ",[60,178,179],{"class":66},"?",[60,181,182],{"class":74}," \u003C",[60,184,185],{"class":94},"Card",[60,187,188],{"class":70}," data",[60,190,107],{"class":66},[60,192,193],{"class":74},"{user} \u002F> ",[60,195,196],{"class":66},":",[60,198,182],{"class":74},[60,200,201],{"class":94},"Spinner",[60,203,204],{"class":74}," \u002F>;\n",[60,206,208],{"class":62,"line":207},9,[60,209,210],{"class":74},"}\n",[10,212,213],{},"This used to require a class component with state, a constructor, and two lifecycle methods. Now it's a handful of lines that say exactly what they do.",[23,215,217],{"id":216},"reuse-that-feels-right","Reuse that feels right",[10,219,220,221,98,224,98,227,230],{},"The real breakthrough for me, though, is custom Hooks. Logic I used to share painstakingly through higher-order components or render props can now live in its own function — ",[14,222,223],{},"useScrollPosition",[14,225,226],{},"useMediaQuery",[14,228,229],{},"useFetch",". It doesn't feel like a trick. It feels like the native language of React.",[10,232,233],{},"That's what good tools are about to me: they don't reduce complexity by hiding things, but by letting you think more clearly. Hooks have made my components smaller, more honest, and easier to test.",[10,235,236,237,239],{},"There are pitfalls, of course. The ",[14,238,20],{}," dependency array wants to be understood, and the rules — only call Hooks at the top level, only inside components — aren't up for negotiation. But those are small prices for a big gain.",[10,241,242],{},"I'm convinced that a year from now we'll look back and see class components for what they were: a good intermediate step. The future is written with functions.",[244,245,246],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":56,"searchDepth":85,"depth":85,"links":248},[249,250],{"id":25,"depth":85,"text":26},{"id":216,"depth":85,"text":217},null,"2019-03-18","React 16.8 brought Hooks in early 2019 — and fundamentally changed how I think about, write, and maintain components.",false,"md","en",{},"\u002Fblog\u002Fen\u002Freact-hooks-change-everything",{"title":5,"description":253},"blog\u002Fen\u002Freact-hooks-change-everything",[262,263,264],"React","Frontend","Development","EEIrgfvDdCktYWzZfT9DExiDLP7Bfw8Mg2SD8ry-RhU",1781596072690]