1. Khi nhiều Component có logic giống nhau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ReactJS</title> </head> <body> <div id="root"></div> <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel"> const { useState, useEffect } = React // User và Photo có logic giống hệt nhau phần get Data về const User = ({ url }) => { const [loading, setLoading] = useState(false) const [dataInfo, setDataInfo] = useState(null) const [failed, setFailed] = useState(null) useEffect(() => { setLoading(true) let fetching = true; fetch(url) .then(res => { if (fetching) { if (res.ok) return res.json() throw { status: res.status, ok: res.ok } } }) .then(res => { if (fetching) { setDataInfo(res) setFailed(null) } }) .catch(err => { if (fetching) { setDataInfo(null) setFailed(err) } }) .finally(() => { setLoading(false) }) return () => fetching = false }, [url]) console.log({ loading, dataInfo, failed }) return ( <div> <h3>User info</h3> {loading && <p>Loading...</p>} {!loading && dataInfo && <p>UserInfo: {JSON.stringify(dataInfo, null, 4)}</p>} {!loading && failed && <p>Failed: {JSON.stringify(failed, null, 4)}</p>} </div> ) } // User và Photo có logic giống hệt nhau phần get Data về const Photo = ({ url }) => { const [loading, setLoading] = useState(false) const [dataInfo, setDataInfo] = useState(null) const [failed, setFailed] = useState(null) useEffect(() => { setLoading(true) let fetching = true; fetch(url) .then(res => { if (fetching) { if (res.ok) return res.json() throw { status: res.status, ok: res.ok } } }) .then(res => { if (fetching) { setDataInfo(res) setFailed(null) } }) .catch(err => { if (fetching) { setDataInfo(null) setFailed(err) } }) .finally(() => { setLoading(false) }) return () => fetching = false }, [url]) console.log({ loading, dataInfo, failed }) return ( <div> <h3>Photo info</h3> {loading && <p>Loading...</p>} {!loading && dataInfo && <p>PhotoInfo: {JSON.stringify(dataInfo, null, 4)}</p>} {!loading && failed && <p>Failed: {JSON.stringify(failed, null, 4)}</p>} </div> ) } const App = () => { const [number, setNumber] = useState(1) return ( <div> <p>Number: {number}</p> <button onClick={() => { setNumber(number + 1) }}>Increase</button> <User url={`https://reqres.in/api/users/${number}`} /> <Photo url={`https://jsonplaceholder.typicode.com/photos/${number}`} /> </div> ) } ReactDOM.render(<App />, document.getElementById('root')) </script> </body> </html> |
2. Tạo thử 1 custom hooks có tên: useFetchData()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ReactJS</title> </head> <body> <div id="root"></div> <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <script type="text/babel"> const { useState, useEffect } = React const useFetchData = (url) => { const [loading, setLoading] = useState(false) const [dataInfo, setDataInfo] = useState(null) const [failed, setFailed] = useState(null) useEffect(() => { setLoading(true) let fetching = true; fetch(url) .then(res => { if (fetching) { if (res.ok) return res.json() throw { status: res.status, ok: res.ok } } }) .then(res => { if (fetching) { setDataInfo(res) setFailed(null) } }) .catch(err => { if (fetching) { setDataInfo(null) setFailed(err) } }) .finally(() => { setLoading(false) }) return () => fetching = false }, [url]) return { loading, dataInfo, failed } } // User và Photo có logic giống hệt nhau phần get Data về const User = ({ url }) => { const { loading, dataInfo, failed } = useFetchData(url) console.log({ loading, dataInfo, failed }) return ( <div> <h3>User info</h3> {loading && <p>Loading...</p>} {!loading && dataInfo && <p>UserInfo: {JSON.stringify(dataInfo, null, 4)}</p>} {!loading && failed && <p>Failed: {JSON.stringify(failed, null, 4)}</p>} </div> ) } // User và Photo có logic giống hệt nhau phần get Data về const Photo = ({ url }) => { const { loading, dataInfo, failed } = useFetchData(url) console.log({ loading, dataInfo, failed }) return ( <div> <h3>Photo info</h3> {loading && <p>Loading...</p>} {!loading && dataInfo && <p>PhotoInfo: {JSON.stringify(dataInfo, null, 4)}</p>} {!loading && failed && <p>Failed: {JSON.stringify(failed, null, 4)}</p>} </div> ) } const App = () => { const [number, setNumber] = useState(1) return ( <div> <p>Number: {number}</p> <button onClick={() => { setNumber(number + 1) }}>Increase</button> <User url={`https://reqres.in/api/users/${number}`} /> <Photo url={`https://jsonplaceholder.typicode.com/photos/${number}`} /> </div> ) } ReactDOM.render(<App />, document.getElementById('root')) </script> </body> </html> |