Understanding React Custom Hooks

--- title: 'Understanding React Custom Hooks' author: 'Hun Im' date: 2023-01-10T18:22:35+09:00 category: ['React', 'Javascript'] og_image: "/images/gamer.png" keywords: ['Javascript', 'React'] --- While using React, I mostly relied on the built-in hooks to handle most of my logic. However, I often pondered how to increase reusability for repetitive code. I believed that effectively using custom hooks would help me become a higher-level frontend developer. The most important principle of custom hooks is "reusability of logic, not values." By specifying only the values related to state changes as parameters within the hook, we can define the logic based on side effects. ```jsx import { useState } from 'react' function App() { const [inputValue, setInputValue] = useState('') const handleChange = (e) => { setInputValue(e.target.value) } const handleSubmit = () => { setInputValue('') } return ( <div> <input value={inputValue} onChange={handleChange} /> <button onClick={handleSubmit}>확인</button> </div> ) } ``` Let's convert the above code into a custom hook. ```js import { useState } from 'react' export function useInput(initialValue, submitAction) { const [inputValue, setInputValue] = useState(initialValue) const handleChange = (e) => { setInputValue(e.target.value) } const handleSubmit = () => { setInputValue('') submitAction(inputValue) } return [inputValue, handleChange, handleSubmit] } ``` ```jsx import { useInput } from 'hooks/useInput' function displayMessage(message) { alert(message) } function App() { const [inputValue, handleChange, handleSubmit] = useInput( 'Hello', displayMessage ) return ( <div> <input value={inputValue} onChange={handleChange} /> <button onClick={handleSubmit}>확인</button> </div> ) } ``` ```jsx import { useState, useEffect } from 'react' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const [data, setData] = useState(null) const fetchUrl = (type) => { fetch(baseUrl + '/' + type) .json() .then((res) => { setData(res) }) } useEffect(() => { fetchUrl('users') }, []) return ( <div> <button onClick={() => fetchUrl('users')}>Users</button> <button onClick={() => fetchUrl('posts')}>Posts</button> <button onClick={() => fetchUrl('todos')}>Todos</button> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ) } ``` Now, let's refactor the above code using a custom hook. ```js import { useEffect, useState } from 'react' export function useFetch(baseUrl, initialType) { const [data, setData] = useState(null) const fetchUrl = (type) => { fetch(baseUrl + '/' + type) .json() .then((res) => { setData(res) }) } useEffect(() => { fetchUrl(initialType) }, []) return { data, fetchUrl, } } ``` ```jsx import { useFetch } from 'hooks/useFetch' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const { data, fetchUrl } = useFetch(baseUrl, 'users') return ( <div> <button onClick={() => fetchUrl('users')}>Users</button> <button onClick={() => fetchUrl('posts')}>Posts</button> <button onClick={() => fetchUrl('todos')}>Todos</button> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ) } ``` ```jsx import { useFetch } from 'hooks/useFetch' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const { data: userData, fetchUrl } = useFetch(baseUrl, 'users') const { data: postData, fetchUrl } = useFetch(baseUrl, 'posts') const { data: todoData, fetchUrl } = useFetch(baseUrl, 'todos') return ( <div>{userData ? <pre>{JSON.stringify(userData[0], null, 2)}</pre> : null}</div> <div>{postData ? <pre>{JSON.stringify(postData[0], null, 2)}</pre> : null}</div> <div>{todoData ? <pre>{JSON.stringify(todoData[0], null, 2)}</pre> : null}</div> ) } ``` Understanding React Custom Hooks
Β 
--- title: 'React Custom hooks μ •ν™•ν•œ 이해' author: 'μž„ν›ˆ' date: 2023-01-10T18:22:35+09:00 category: ['React', 'Javascript'] og_image: "/images/gamer.png" keywords: ['Javascript', 'React'] --- κ·Έλ™μ•ˆ λ¦¬μ•‘νŠΈλ₯Ό μ‚¬μš©ν•΄ μ˜€λ©΄μ„œ, κΈ°λ³Έ hooksλ₯Ό μ΄μš©ν•˜μ—¬ λŒ€λΆ€λΆ„μ˜ λ‘œμ§μ„ μˆ˜ν–‰ν–ˆλ‹€. ν•˜μ§€λ§Œ λ°˜λ³΅λ˜λŠ” μ½”λ“œμ— λŒ€ν•΄ 항상 μ–΄λ–»κ²Œ ν•˜λ©΄ μž¬μ‚¬μš©μ„±μ„ 늘릴 수 μžˆμ„κΉŒ κ³ λ―Ό ν–ˆμ—ˆλ‹€. μ»€μŠ€ν…€ 훅을 잘 μ‚¬μš©ν•˜λ©΄ 더 높은 레벨의 ν”„λ‘ νŠΈμ—”λ“œ κ°œλ°œμžκ°€ 될 것 κ°™μ•˜λ‹€. μ»€μŠ€ν…€ ν›…μ˜ κ°€μž₯ μ€‘μš”ν•œ 원칙은 'κ°’μ˜ μž¬μ‚¬μš©μ΄ μ•„λ‹Œ 둜직의 μž¬μ‚¬μš©' 이닀. ν›… 내뢀에 μƒνƒœ 변화에 λŒ€ν•œ κ°’λ§Œ λ§€κ°œλ³€μˆ˜λ‘œ μ§€μ •ν•΄μ£Όμ–΄, Side effect에 λ”°λ₯Έ λ‘œμ§μ„ μ •ν•΄μ€€λ‹€. ```jsx import { useState } from 'react' function App() { const [inputValue, setInputValue] = useState('') const handleChange = (e) => { setInputValue(e.target.value) } const handleSubmit = () => { setInputValue('') } return ( <div> <input value={inputValue} onChange={handleChange} /> <button onClick={handleSubmit}>확인</button> </div> ) } ``` μœ„μ˜ μ½”λ“œλ₯Ό custom hook으둜 λ§Œλ“€μ–΄λ³΄μž. ```js import { useState } from 'react' export function useInput(initialValue, submitAction) { const [inputValue, setInputValue] = useState(initialValue) const handleChange = (e) => { setInputValue(e.target.value) } const handleSubmit = () => { setInputValue('') submitAction(inputValue) } return [inputValue, handleChange, handleSubmit] } ``` ```jsx import { useInput } from 'hooks/useInput' function displayMessage(message) { alert(message) } function App() { const [inputValue, handleChange, handleSubmit] = useInput( 'Hello', displayMessage ) return ( <div> <input value={inputValue} onChange={handleChange} /> <button onClick={handleSubmit}>확인</button> </div> ) } ``` ```jsx import { useState, useEffect } from 'react' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const [data, setData] = useState(null) const fetchUrl = (type) => { fetch(baseUrl + '/' + type) .json() .then((res) => { setData(res) }) } useEffect(() => { fetchUrl('users') }, []) return ( <div> <button onClick={() => fetchUrl('users')}>Users</button> <button onClick={() => fetchUrl('posts')}>Posts</button> <button onClick={() => fetchUrl('todos')}>Todos</button> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ) } ``` μœ„μ˜ μ½”λ“œλ₯Ό custom hook을 μ΄μš©ν•œ 둜직으둜 λ°”κΏ”λ³΄μž. ```js import { useEffect, useState } from 'react' export function useFetch(baseUrl, initialType) { const [data, setData] = useState(null) const fetchUrl = (type) => { fetch(baseUrl + '/' + type) .json() .then((res) => { setData(res) }) } useEffect(() => { fetchUrl(initialType) }, []) return { data, fetchUrl, } } ``` ```jsx import { useFetch } from 'hooks/useFetch' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const { data, fetchUrl } = useFetch(baseUrl, 'users') return ( <div> <button onClick={() => fetchUrl('users')}>Users</button> <button onClick={() => fetchUrl('posts')}>Posts</button> <button onClick={() => fetchUrl('todos')}>Todos</button> <pre>{JSON.stringify(data, null, 2)}</pre> </div> ) } ``` ```jsx import { useFetch } from 'hooks/useFetch' const baseUrl = 'https://jsonplaceholder.typicode.com' function App() { const { data: userData, fetchUrl } = useFetch(baseUrl, 'users') const { data: postData, fetchUrl } = useFetch(baseUrl, 'posts') const { data: todoData, fetchUrl } = useFetch(baseUrl, 'todos') return ( <div>{userData ? <pre>{JSON.stringify(userData[0], null, 2)}</pre> : null}</div> <div>{postData ? <pre>{JSON.stringify(postData[0], null, 2)}</pre> : null}</div> <div>{todoData ? <pre>{JSON.stringify(todoData[0], null, 2)}</pre> : null}</div> ) } ```