{"id":281073,"date":"2019-01-18T08:15:02","date_gmt":"2019-01-18T15:15:02","guid":{"rendered":"http:\/\/css-tricks.com\/?p=281073"},"modified":"2020-05-01T14:27:43","modified_gmt":"2020-05-01T21:27:43","slug":"intro-to-react-hooks","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/intro-to-react-hooks\/","title":{"rendered":"Intro to React Hooks"},"content":{"rendered":"\n
Hooks make it possible to organize logic in components, making them tiny and reusable without writing a class. In a sense, they\u2019re React\u2019s way of leaning into functions because, before them, we\u2019d have to write them in a component and, while components have proven to be powerful and functional in and of themselves, they have to render something on the front end. That\u2019s all fine and dandy to some extent, but the result is a DOM that is littered with divs that make it gnarly to dig through through DevTools and debug.<\/p>\n\n\n\n
Well, React Hooks change that. Instead of relying on the top-down flow of components or abstracting components in various ways, like higher-order components<\/a>, we can call and manage flow inside of a component. Dan Abramov explains it well in his Making Sense of React<\/a> post:<\/p>\n\n\n\n\n\n\n\n Hooks apply the React philosophy (explicit data flow and composition) inside<\/em> a component, rather than just between<\/em> the components.<\/strong> That\u2019s why I feel that Hooks are a natural fit for the React component model.<\/p> Unlike patterns like render props or higher-order components, Hooks don\u2019t introduce unnecessary nesting into your component tree. They also don\u2019t suffer from the drawbacks of mixins.<\/p><\/blockquote>\n\n\n\n The rest of Dan\u2019s post provides a lot of useful context for why the React team is moving in this direction (they’re now available in React v16.7.0-alpha) and the various problems that hooks are designed to solve. The React docs have an introduction to hooks<\/a> that, in turn, contains a section on what motivated the team to make them<\/a>. We\u2019re more concerned with how the heck to use them, so let\u2019s move on to some examples!<\/p>\n\n\n\n The important thing to note as we get started is that there are nine hooks currently available, but we’re going to look at what the React docs call the three basic ones: If you\u2019ve worked with React at any level, then you\u2019re probably familiar with how state is generally defined: write a class and use React hooks allow us to scrap all that class stuff and put the Say what?! That\u2019s it! Notice that we\u2019re working outside of a class. Hooks don\u2019t work inside of a class because they\u2019re used in place of them. We\u2019re using the hook directly in the component:<\/p>\n\n\n\n Oh, you want to update the state of name? Let\u2019s add an input and submit button to the output and call useState()<\/code>, useEffect<\/code>, and setContext()<\/code>. We\u2019ll dig into each one in this post with a summary of the advanced hooks at the end.<\/p>\n\n\nDefining state with
useState()<\/code><\/h3>\n\n\nthis.state<\/code> to initialize a class:<\/p>\n\n\n\nclass SomeComponent extends React.component {\n constructor(props)\n super(props);\n this.state = {\n name: Barney Stinson \/\/ Some property with the default state value \n }\n}<\/code><\/pre>\n\n\n\nuseState()<\/code> hook to use instead. Something like this:<\/p>\n\n\n\nimport { useState } from 'react';\n \nfunction SomeComponent() {\n const [name, setName] = useState('Barney Stinson'); \/\/ Defines state variable (name) and call (setName) -- both of which can be named anything\n}<\/code><\/pre>\n\n\n\nimport { useState } from 'react';\n \nfunction SomeComponent() {\n const [name, setName] = useState('Barney Stinson');\n \n return\n <div>\n <p>Howdy, {name}<\/p>\n <\/div>\n}<\/code><\/pre>\n\n\n\nsetName<\/code> to update the default name on submission.<\/p>\n\n\n\nimport { useState } from 'react'\n \nfunction SomeComponent() {\n const [input, setValue] = useState(\"\");\n const [name, setName] = useState('Barney Stinson');\n \n handleInput = (event) => {\n setValue(event.target.value);\n }\n \n updateName = (event) => {\n event.preventDefault();\n setName(input);\n setValue(\"\");\n }\n \n return (\n <div>\n <p>Hello, {name}!<\/p>\n <div>\n <input type=\"text\" value={input} onChange={handleInput} \/>\n <button onClick={updateName}>Save<\/button>\n <\/div>\n <\/div>\n )\n}<\/code><\/pre>\n\n\n\n