1. Đặt vấn đề
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 |
<!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 // Hình chữ nhật và hình tròn có logic về opacity khá giống nhau const Rectangle = () => { const [opacity, setOpacity] = useState(1); return ( <div style={{ opacity }} onMouseEnter={() => setOpacity(0.5)} onMouseLeave={() => setOpacity(1)} > <div style={{ width: 200, height: 100, backgroundColor: "green" }}></div> </div> ) } // Hình chữ nhật và hình tròn có logic về opacity khá giống nhau const Circle = ({ url }) => { const [opacity, setOpacity] = useState(1); return ( <div style={{ opacity }} onMouseEnter={() => setOpacity(0.5)} onMouseLeave={() => setOpacity(1)} > <div style={{ width: 100, height: 100, backgroundColor: "violet", borderRadius: "50%" }}></div> </div> ) } const App = () => { return ( <div> <Circle /> <Rectangle /> </div> ) } ReactDOM.render(<App />, document.getElementById('root')) </script> </body> </html> |
2. Dùng HOC để giải quyết các logic trùng lặp
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 |
<!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 // Tạo 1 HOC nhận vào một Component và trả về một Component // HOC này dự định sẽ dùng chung cho mọi Component có logic di chuột vào làm mờ hình const withHoverOpacity = (CustomComponent) => () => { const [opacity, setOpacity] = useState(1); return ( <div style={{ opacity }} onMouseEnter={() => setOpacity(0.5)} onMouseLeave={() => setOpacity(1)} > <CustomComponent/> </div> ) } const Rectangle = () => <div style={{ width: 200, height: 100, backgroundColor: "green" }}></div> const Circle = () => <div style={{ width: 100, height: 100, backgroundColor: "violet", borderRadius: "50%" }}></div> // Tạo thêm 1 component cha từ HOC bọc lại Component ban đầu const RectangleWithHover = withHoverOpacity(Rectangle) const CircleWithHover = withHoverOpacity(Circle) const App = () => { return ( <div> <RectangleWithHover /> <CircleWithHover /> </div> ) } ReactDOM.render(<App />, document.getElementById('root')) </script> </body> </html> |