0% found this document useful (0 votes)
62 views

React JS

The document discusses React.createElement and how it is used to create React elements programmatically. It provides examples of creating DOM elements with document.createElement vs creating React elements with React.createElement. It also covers rendering React elements to the DOM with ReactDOM.render, using JSX as an alternative syntax, and creating React component classes.

Uploaded by

Hiếu Nguyễn
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views

React JS

The document discusses React.createElement and how it is used to create React elements programmatically. It provides examples of creating DOM elements with document.createElement vs creating React elements with React.createElement. It also covers rendering React elements to the DOM with ReactDOM.render, using JSX as an alternative syntax, and creating React component classes.

Uploaded by

Hiếu Nguyễn
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 49

React.

createElement( type, props, children, n)

Example:

const h1React = React.createElement('h1', {

            title: 'Hello',

            className: 'heading'

        }, 'Hello guys!')

        const ulDOM = document.createElement('ul')

        ulDOM.id = 'ul-id'

        ulDOM.style = 'color: red; font-size: 30px'

        const liDOM1 = document.createElement('li')

        liDOM1.innerText = 'Javascript'

        liDOM1.id = 'li-1'

        const liDOM2 = document.createElement('li')

        liDOM2.innerText = 'ReacJS'

        ulDOM.appendChild(liDOM1)

        ulDOM.appendChild(liDOM2)

        document.body.appendChild(ulDOM)

        // React

        const ulReact = React.createElement(

            'ul',

            {

                id: 'ul-id',

                style: 'color: red; font-size: 30px'

            },
            React.createElement('li', {id: 'li-1'}, 'Javascript'),

            React.createElement('li', null, 'ReacJS'),

        )

Exercises:

        const divDOM = document.createElement('div')

        divDOM.className = 'post-item'

        const h2DOM = document.createElement('h2')

        h2DOM.title = 'Học React tại F8'

        h2DOM.innerText = 'Học ReactJS'

        const pDOM = document.createElement('p')

        pDOM.innerText = 'Học ReactJS từ cơ bản tới nâng cao'

        divDOM.appendChild(h2DOM)

        divDOM.appendChild(pDOM)

        document.body.appendChild(divDOM)

        // React

        const reactDOM = React.createElement(

            'div',

            {className: 'post-item'},

            React.createElement('h2', {title: 'Học React tại F8'}, 'Học

ReactJS'),

            React.createElement('p', null, 'Học ReactJS từ cơ bản tới nâng

cao')

        )
ReactDOM.render( element, container, callback)

Example:

       // React

        const postItem = React.createElement(

            'div',

            {className: 'post-item'},

            React.createElement('h2', {title: 'Học React tại F8'}, 'Học

ReactJS'),

            React.createElement('p', null, 'Học ReactJS từ cơ bản tới nâng

cao')

        )

        // Get root element

        const container = document.getElementById('root')

        // React@17

        // React-DOm -> render UI

        // ReactDOM.render(postItem, root)

        // React@18

        const root = ReactDOM.createRoot(container)

        root.render(postItem)
JSX

Example:

    <script type="text/babel">

        // React

        const courses = [

            {

                name: 'HTML, CSS'

            },

            {

                name: 'Responsive web design'

            },

            {

                name: 'ReactJS'

            }

        ]

        const course = courses.map((course, index)=>{

            return <li key={index}>{course.name}</li>

        });

        const ul = <ul>

                {course}

            </ul>

        // React@18

        const container = document.getElementById('root')

        const root = ReactDOM.createRoot(container)

        root.render(ul)

    </script>
React.Fragment dùng để tạo ra lớp giả để chứa 2 element cùng cấp

Example:

        const jsx = React.createElement(

            React.Fragment,

            null,

            React.createElement('h1', null, 'Heading 1'),

            React.createElement('h2', null, 'Heading 2')

        )

        const jsx = (

            <React.Fragment>

                <h1>Heading 1</h1>

                <h2>Heading 2</h2>

            </React.Fragment>

        )

React element types

Example:

        function Header() {

            return (

                <div className="header">New Header</div>

            )

        }

        class Content extends React.Component {

            render() {

                return (

                    <div className="content">New Content</div>

                )

            }

        }
        const app = (

            <div className="wrapper">

                <Header></Header>

                <Content></Content>

                <div className="footer">Footer</div>

            </div>

        )

        const container = document.getElementById('app')

        const root = ReactDOM.createRoot(container)

        root.render(app)

Exercises:

        function PostItem() {

            return (

                <div className="post-item">

                    <img src="https://media-cdn.tripadvisor.com/media/photo-

s/12/45/4d/03/anhr-tren-d-i-nhin-v.jpg"/>

                    <h2 className="post-title">Nguyen Trung Hieu</h2>

                    <p className="posts-desc">Đẹp trai, thông minh, vui

tính</p>

                    <p className="posts-published">2 days ago</p>    

                </div>

            )

        }

        const app = (

            <div className="posts-list">

                <PostItem />

                <PostItem />
            </div>

        )

        const container = document.getElementById('app')

        const root = ReactDOM.createRoot(container)

        root.render(app)

-----------------------------------------------------------------------------------

props

        function PostItem(props) {

            return (

                <div className="post-item">

                    <img src={props.image}/>

                    <h2 className="post-title">{props.title}</h2>

                    <p className="posts-desc">{props.desciption}</p>

                    <p className="posts-published">{props.publishedAt}</p>  

                </div>

            )

        }

        const app = (

            <div className="posts-list">

                <PostItem

                   

image="https://media-cdn.tripadvisor.com/media/photo-s/12/45/4d/03/anhr-tren-

d-i-nhin-v.jpg"

                    title="Nguyen Trung Hieu"

                    desciption="Đẹp trai, thông minh, vui tính"

                    publishedAt="2 days ago"

                />

            </div>
        )
Sử dụng destructuring

        function PostItem({

            image,

            title,

            desciption,

            publishedAt

        }) {

            return (

                <div className="post-item">

                    <img src={image} />

                    <h2 className="post-title">{title}</h2>

                    <p className="posts-desc">{desciption}</p>

                    <p className="posts-published">{publishedAt}</p>

                </div>

            )

        }

        const app = (

            <div className="posts-list">

                <PostItem

                   

image="https://media-cdn.tripadvisor.com/media/photo-s/12/45/4d/03/anhr-tren-

d-i-nhin-v.jpg"

                    title="Nguyen Trung Hieu"

                    desciption="Đẹp trai, thông minh, vui tính"

                    publishedAt="2 days ago"

                />

            </div>

        )
Exercise:

        const courses = [

            {

                "id": 7,

                "title": "Kiến Thức Nhập Môn IT",

                "slug": "lessons-for-newbie",

                "description": "Để có cái nhìn tổng quan về ngành IT - Lập

trình web các bạn nên xem các videos tại khóa này trước nhé.",

                "image": "courses/7.png",

                "icon": "courses/7/6200b81f52d83.png",

                "video_type": "youtube",

                "video": "M62l1xA5Eu8",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 75848,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 66,

                "last_completed_at": "2022-01-24 14:49:26",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/7.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/7/6200b81f52d83.png",

                "video_url": "https://www.youtube.com/watch?v=M62l1xA5Eu8",

                "landing_page_url": "/courses/lessons-for-newbie",

                "is_coming_soon": false,
                "is_pre_order": false,

                "is_published": true

            },

            {

                "id": 2,

                "title": "HTML, CSS từ Zero đến Hero",

                "slug": "html-css",

                "description": "Trong khóa này chúng ta sẽ cùng nhau xây dựng

giao diện 2 trang web là The Band & Shopee.",

                "image": "courses/2.png",

                "icon": "courses/2/6200aecea81de.png",

                "video_type": "youtube",

                "video": "R6plN3FvzFY",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 118416,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 99,

                "last_completed_at": "2022-06-13 10:45:44",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/2.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/2/6200aecea81de.png",

                "video_url": "https://www.youtube.com/watch?v=R6plN3FvzFY",

                "landing_page_url": "/courses/html-css",

                "is_coming_soon": false,

                "is_pre_order": false,
                "is_published": true

            },

            {

                "id": 3,

                "title": "Responsive Với Grid System",

                "slug": "responsive-web-design",

                "description": "Trong khóa này chúng ta sẽ học về cách xây

dựng giao diện web responsive với Grid System, tương tự Bootstrap 4.",

                "image": "courses/3.png",

                "icon": "courses/3/6200afe1240bb.png",

                "video_type": "youtube",

                "video": "uz5LIP85J5Y",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 26794,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 91,

                "last_completed_at": "2022-06-15 13:38:27",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/3.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/3/6200afe1240bb.png",

                "video_url": "https://www.youtube.com/watch?v=uz5LIP85J5Y",

                "landing_page_url": "/courses/responsive-web-design",

                "is_coming_soon": false,

                "is_pre_order": false,

                "is_published": true
            },

            {

                "id": 1,

                "title": "Lập Trình JavaScript Cơ Bản",

                "slug": "javascript-co-ban",

                "description": "Học Javascript cơ bản phù hợp cho người chưa

từng học lập trình. Với hơn 100 bài học và có bài tập thực hành sau mỗi bài

học.",

                "image": "courses/1.png",

                "icon": "courses/1/6200ad9d8a2d8.png",

                "video_type": "youtube",

                "video": "0SJE9dYdpps",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 75964,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 100,

                "last_completed_at": "2022-07-21 00:08:38",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/1.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/1/6200ad9d8a2d8.png",

                "video_url": "https://www.youtube.com/watch?v=0SJE9dYdpps",

                "landing_page_url": "/courses/javascript-co-ban",

                "is_coming_soon": false,

                "is_pre_order": false,

                "is_published": true
            },

            {

                "id": 12,

                "title": "Lập Trình JavaScript Nâng Cao",

                "slug": "javascript-nang-cao",

                "description": "Hiểu sâu hơn về cách Javascript hoạt động, tìm

hiểu về IIFE, closure, reference types, this keyword, bind, call, apply,

prototype, ...",

                "image": "courses/12.png",

                "icon": "courses/12/6200af2620118.png",

                "video_type": "youtube",

                "video": "MGhw6XliFgo",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 18997,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 89,

                "last_completed_at": "2022-07-31 14:03:14",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/12.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/12/6200af2620118.png",

                "video_url": "https://www.youtube.com/watch?v=MGhw6XliFgo",

                "landing_page_url": "/courses/javascript-nang-cao",

                "is_coming_soon": false,

                "is_pre_order": false,

                "is_published": true
            },

            {

                "id": 14,

                "title": "Làm việc với Terminal & Ubuntu",

                "slug": "windows-terminal-wsl",

                "description": "Sở hữu một Terminal hiện đại, mạnh mẽ trong

tùy biến và học cách làm việc với Ubuntu là một bước quan trọng trên con đường

trở thành một Web Developer.",

                "image": "courses/14/624faac11d109.png",

                "icon": "courses/14/624faac2ee23d.png",

                "video_type": "youtube",

                "video": "7ppRSaGT1uw",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 5724,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 66,

                "last_completed_at": "2022-07-31 23:23:11",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/14/624faac11d109.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/14/624faac2ee23d.png",

                "video_url": "https://www.youtube.com/watch?v=7ppRSaGT1uw",

                "landing_page_url": "/courses/windows-terminal-wsl",

                "is_coming_soon": false,

                "is_pre_order": false,

                "is_published": true
            },

            {

                "id": 13,

                "title": "Xây Dựng Website với ReactJS",

                "slug": "reactjs",

                "description": "Khóa học ReactJS từ cơ bản tới nâng cao, kết

quả của khóa học này là bạn có thể làm hầu hết các dự án thường gặp với

ReactJS. Cuối khóa học này bạn sẽ sở hữu một dự án giống Tiktok.com, bạn có

thể tự tin đi xin việc khi nắm chắc các kiến thức được chia sẻ trong khóa học

này.",

                "image": "courses/13/13.png",

                "icon": "courses/13/6200af9262b30.png",

                "video_type": "youtube",

                "video": "x0fSBAgBrOQ",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 29462,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 25,

                "last_completed_at": "2022-08-06 15:55:03",

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/13/13.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/13/6200af9262b30.png",

                "video_url": "https://www.youtube.com/watch?v=x0fSBAgBrOQ",

                "landing_page_url": "/courses/reactjs",

                "is_coming_soon": false,
                "is_pre_order": false,

                "is_published": true

            },

            {

                "id": 6,

                "title": "Node & ExpressJS",

                "slug": "nodejs",

                "description": "Học Back-end với Node & ExpressJS framework,

hiểu các khái niệm khi làm Back-end và xây dựng RESTful API cho trang web.",

                "image": "courses/6.png",

                "icon": "courses/6/6200afb926038.png",

                "video_type": "youtube",

                "video": "z2f7RHgvddc",

                "old_price": 0,

                "price": 0,

                "pre_order_price": 0,

                "students_count": 21957,

                "is_pro": false,

                "is_selling": false,

                "published_at": "2020-02-10T14:23:13.000000Z",

                "is_registered": true,

                "user_progress": 0,

                "last_completed_at": null,

                "image_url":

"https://files.fullstack.edu.vn/f8-prod/courses/6.png",

                "icon_url":

"https://files.fullstack.edu.vn/f8-prod/courses/6/6200afb926038.png",

                "video_url": "https://www.youtube.com/watch?v=z2f7RHgvddc",

                "landing_page_url": "/courses/nodejs",

                "is_coming_soon": false,

                "is_pre_order": false,
                "is_published": true

            }

        ]

        function CourseItem({course}) {

            return (

                <div className="course-item">

                    <img src={course.image_url} alt={course.slug} />

                    <h2 className="course-title">{course.title}</h2>

                    <p className="course-desc">{course.description}</p>

                    <p className="course-student">{course.students_count}</p>

                </div>

            )

        }

        function App() {

            return (

                <div className="wrapper">

                    {

                        courses.map((course, index) => (

                            <CourseItem

                                key={course.id}

                                course={course}

                            />

                        ))

                    }

                </div>

            )

        }
        const root = ReactDOM.createRoot(document.getElementById("root"));

        root.render(<App />)
DOM events

Example:

        function App() {

            return (

                <div className="wrapper">

                    <button

                        onClick={(e) =>

                            console.log(e.target)

                        }

                    >

                        Click me!

                    </button>

                </div>

            )

        }

Exercise:

        function CourseItem({course, onClick}) {

            return (

                <div className="course-item">

                    <img src={course.image_url} alt={course.slug} />

                    <h1 className="course-published">{course.slug}</h1>

                    <h2 className="course-title" onClick={() =>

onClick(course)} >{course.title}</h2>

                    <p className="course-desc">{course.description}</p>

                    <p className="course-student">{course.studentsCount}</p>

                </div>

            )
        }

        function App() {

            const handleClick = (course) => {

                alert(course.title)

            }

            return (

                <div className="wrapper">

                    {

                        courses.map((course, index) => (

                            <CourseItem

                                key={course.id}

                                course={course}

                                onClick={handleClick}

                            />

                        ))

                    }

                </div>

            )

        }

        const Form = {

            Input() {

                return <input/>

            },

            Checkbox() {

                return <input type="checkbox" />

            }

        }
        function App() {

            return (

                <div className="wrapper">

                    <Form.Input />

                </div>

            )

        }

        const Form = {

            Input() {

                return <input/>

            },

            Checkbox() {

                return <input type="checkbox" />

            }

        }

        function App() {

            const type = 'Checkbox'

            const Component = Form[type]

            return (

                <div className="wrapper">

                    <Component />

                </div>

            )

        }

        function Button({title, href, onClick}) {

            let Component = 'button'

            const props = {}
            if(href) {

                Component = 'a'

                props.href = href

            }

            if(onClick) {

                props.onClick = onClick

            }

           

            return (

                <Component {...props}>{title}</Component>

            )

        }

        function App() {

            return (

                <div className="wrapper">

                   <Button

                        title="Click me!"

                        href="https://www.facebook.com/"

                        onClick={() => console.log(Math.random())}

                   />

                </div>

            )

        }

Spread/React props

        function Input({label, ...inputProps}) {

            return (

                <div>
                    <label>{label}</label>

                    <input {...inputProps}/>

                </div>

            )

        }

        function App() {

            return (

                <div className="wrapper">

                    <Input

                        label="Full name"

                        type="checkbox"

                        placeholder="Enter name...."

                    />

                </div>

            )

        }

Children props

function Button({children}) {

            return (

                <button>{children}</button>

            )

        }

        function App() {

            return (

                <div className="wrapper">

                    <Button>Click me!</Button>

                </div>

            )
        }

Render props

        function List({data}) {

            return (

                <ul>

                    {data.map(item =>

                        <li key={item}>{item}</li>

                    )}

                </ul>

            )

        }

       

        function App() {

            const cars = ['BMW', 'Honda', 'Mazda']

            return (

                <div className="wrapper">

                    <List data={cars}/>

                </div>

            )

        }

function List({ data, children }) {

            return (

                <ul>

                    {data.map((item, index) => children(item, index))}

                </ul>

            )

        }
        function App() {

            const cars = ['BMW', 'Honda', 'Mazda']

            return (

                <div className="wrapper">

                    <List data={cars}>

                        {(item, index) => <li key={index}>{item}</li>}

                    </List>

                </div>

            )

        }

useState()

function App() {

  const [counter, setCounter] = useState(1)

  const handleIncrease = () => {

    setCounter(counter+1)

  }

  return (

    <div className="App" style={{padding: 20}}>

      <h1>{counter}</h1>

      <button onClick={handleIncrease}>Increase</button>

    </div>

  );

function App() {

  const [counter, setCounter] = useState(() => {

    const total = orders.reduce((total, cur) => total + cur)

    return total

  })
  const handleIncrease = () => {

    setCounter(counter + 1)

  }

  return (

    <div className="App" style={{ padding: 20 }}>

      <h1>{counter}</h1>

      <button onClick={handleIncrease}>Increase</button>

    </div>

  );

function App() {

  const [info, setInfo] = useState({

    name: 'Nguyen Trung Hieu',

    age: 20,

    address: 'Da Nang, Viet Nam'

  })

  const handleUpdate = () => {

    setInfo({

      ...info,

      bio: 'Yeu mau hong'

    })

  }

  return (

    <div className="App" style={{ padding: 20 }}>

      <h1>{JSON.stringify(info)}</h1>

      <button onClick={handleUpdate}>Update</button>

    </div>

  );

}
Example:

Random gifts

const gifts = [

  'CPU i9',

  'RAM 32GB RGB',

  'RGB Keyboard',

function App() {

  const [gift, setGift] = useState()

  const randomGift = () => {

    const index = Math.floor(Math.random() * gifts.length)

    setGift(gifts[index])

  }

  return (

    <div className="App" style={{ padding: 20 }}>

      <h1>{gift ||'Chưa có phần phưởng'}</h1>

      <button onClick={randomGift}>Lấy thưởng</button>

    </div>

  );

Two-way building

function App() {

  const [name, setName] =useState('')

  console.log(name)

  return (

    <div className="App" style={{ padding: 20 }}>

      <input value={name} onChange={e => setName(e.target.value)}></input>


      <button onClick={() => setName('Nguyen Van BB')}>Change</button>

    </div>

  );

function App() {

  const [name, setName] =useState('')

  const [email, setEmail] =useState('')

  const handleSubmit = () => {

    console.log({

      name,

      email

    })

  }

  return (

    <div className="App" style={{ padding: 20 }}>

      <input value={name} onChange={e => setName(e.target.value)}></input>

      <input value={email} onChange={e => setEmail(e.target.value)}></input>

      <button onClick={handleSubmit}>Register</button>

    </div>

  );

const courses = [

  {

    id: 1,

    name: 'HTML, CSS'

  },

  {
    id: 2,

    name: 'Javascript'

  },

  {

    id: 3,

    name: 'ReactJS'

  },

function App() {

  const [checked, setChecked] = useState([])

  console.log(checked)

  const handleCheck = (id) => {

    setChecked(prev => {

      const isChecked = checked.includes(id)

      if(isChecked) {

        return checked.filter(item => item !== id)

      } else {

        return [...prev, id]

      }

    })

  }

  const handleSubmit = () => {

    console.log({ids: checked})

  }

  return (

    <div className="App" style={{ padding: 20 }}>


      {courses.map(course => (

        <div key={course.id}>

          <input type="checkbox" onChange={() => handleCheck(course.id)}

checked={checked.includes(course.id)}/>

          <label>{course.name}</label>

        </div>

      ))}

      <button onClick={handleSubmit}>Register</button>

    </div>

  );

function App() {

  const [job, setJob] = useState('');

  const [jobs, setJobs] = useState(() => {

    const storageJobs = JSON.parse(localStorage.getItem('jobs'))

    return storageJobs

  });

  const handleSubmit = () => {

    setJobs((prev) => {

      const newJobs = [...prev, job]

      const jsonJobs = JSON.stringify(newJobs)

      localStorage.setItem('jobs', jsonJobs)

      return newJobs

    });

    setJob('');
  };

  return (

    <div className="App" style={{ padding: 20 }}>

      <input value={job} onChange={(e) => setJob(e.target.value)}></input>

      <button onClick={handleSubmit}>Add</button>

      <ul>

        {jobs.map((job, index) => (

          <li key={index}>{job}</li>

        ))}

      </ul>

    </div>

  );

Mounted / Unmounted

function App() {

  const [show, setShow] = useState(false)

  return (

    <div className="App" style={{ padding: 20 }}>

      <button onClick={() => setShow(!show)}>Toggle</button>

      {show && <Content></Content>}

    </div>

  );

}
useEffect

// 1. useEffect(callback)

// - Gọi callback mỗi khi component re-render

// - Gọi callback sau khi component thêm element vào DOM

// 2. useEffect(callback, [])

// - Chỉ gọi callback 1 lần sau khi component mounted

// 3. useEffect(callback, [deps])

// - Callback sẽ được gọi lại mỗi khi deps thay đổi

// -----------------------------

// 1. Callback luôn được gọi sau khi component mounted

// 2. Cleanup function luôn được gọi trước khi component unmounted

// 3. Cleanup function luôn được gọi trước khi callback được gọi (trừ lần

mounted)

function Content() {

    const [title, setTitle] = useState('')

    const [posts, setPosts] = useState([])

    useEffect(() => {

        fetch('https://jsonplaceholder.typicode.com/posts')

            .then(res =>  res.json())

            .then(posts => {

                setPosts(posts)

            })

    }, [])

    return (

        <div>
            <input value={title} onChange={e =>

setTitle(e.target.value)}></input>

            <ul>

                {posts.map(post => (

                    <li key={post.id}>{post.title}</li>

                ))}

            </ul>

        </div>

    )

}
Call API

const tabs = ['posts', 'comments', 'albums']

function Content() {

    const [title, setTitle] = useState('')

    const [posts, setPosts] = useState([])

    const [type, setType] = useState('posts')

    useEffect(() => {

        fetch(`https://jsonplaceholder.typicode.com/${type}`)

            .then(res =>  res.json())

            .then(posts => {

                setPosts(posts)

            })

    }, [type])

    return (

        <div>

            {tabs.map(tab => (

                <button key={tab} onClick={() => setType(tab)} style={type

=== tab ? {color: '#fff', backgroundColor: '#333'} : {}}>


                    {tab}

                </button>

            ))}

            <input value={title} onChange={e =>

setTitle(e.target.value)}></input>

            <ul>

                {posts.map(post => (

                    <li key={post.id}>{post.title}</li>

                ))}

            </ul>

        </div>

    )

}
Button go to top

const tabs = ['posts', 'comments', 'albums']

function Content() {

    const [title, setTitle] = useState('')

    const [posts, setPosts] = useState([])

    const [type, setType] = useState('posts')

    const [showGoToTop, setShowGoToTop] = useState(false)

    useEffect(() => {

        fetch(`https://jsonplaceholder.typicode.com/${type}`)

            .then(res => res.json())

            .then(posts => setPosts(posts))

    }, [type])
    useEffect(() => {

        const handleScroll = () => {

            if (window.scrollY >= 200) {

                setShowGoToTop(true)

            } else {

                setShowGoToTop(false)

            }

        }

        window.addEventListener('scroll', handleScroll)

        // Cleanup function

        return () => {

            window.removeEventListener('scroll', handleScroll)

        }

    }, [])

    return (

        <div>

            {tabs.map(tab => (

                <button key={tab}

                    style={tab === type ? { color: '#fff', backgroundColor:

'#333' } : {}}

                    onClick={() => setType(tab)}

                >{tab}</button>

            ))}

            {posts.map(post => (

                <li key={post.id}>{post.title}</li>

            ))}

            {showGoToTop && (

                <button style={{ position: 'fixed', right: 20, bottom: 20 }}>


                    Go to top

                </button>

            )}

        </div>

    )

}
Resize

function Content() {

    const [width, setWidth] = useState(window.innerWidth)

    useEffect(() => {

        const handleResize = () => {

            setWidth(window.innerWidth)

        }

        window.addEventListener('resize', handleResize)

        // Cleanup function

        return () => {

            window.removeEventListener('resize', handleResize)

        }

    }, [])

    return (

        <div>

            <h1>{width}</h1>

        </div>

    )

}
Countdown

function Content() {

    const [countdown, setCountdown] = useState(180)

    useEffect(() => {

        const timerId = setInterval(() => {

            setCountdown(prev => prev - 1)

        }, 1000)

        return () => clearInterval(timerId)

    }, [])

    return (

        <div>

            <h1>{countdown}</h1>

        </div>

    )

}
Preview avatar

function Content() {

    const [avatar, setAvatar] = useState()

    useEffect(() => {

        return () => {

            avatar && URL.revokeObjectURL(avatar.preview)

        }

    }, [avatar])

    const handlePreviewAvatar = (e) => {

        const file = e.target.files[0]


        file.preview = URL.createObjectURL(file)

        setAvatar(file)

    }

    return (

        <div>

            <input type="file" onChange={handlePreviewAvatar} />

            {avatar && (

                <img src={avatar.preview} alt="" width="80%" />

            )}

        </div>

    )

}
Fake app chat

// Fake comments

function emitComment(id) {

  setInterval(() => {

    window.dispatchEvent(

      new CustomEvent(`lesson-${id}`, {

        detail: `nội dung comment của lesson ${id}`

      })

    )

  }, 2000)

emitComment(1)

emitComment(2)

emitComment(3)

const lessons = [

    {
        id: 1,

        name: 'ReactJS là gì? Tại sao nên học ReactJS'

    },

    {

        id: 2,

        name: 'SPA/MPA là gì?'

    },

    {

        id: 3,

        name: 'Arrow function'

    }

function Content() {

    const [lessonId, setLessonId] = useState(1)

    useEffect(() => {

        const handleComment = ({detail}) => {

            console.log(detail)

        }

        window.addEventListener(`lesson-${lessonId}`, handleComment)

        return () => {

        window.removeEventListener(`lesson-${lessonId}`, handleComment)

        }

    }, [lessonId])

    return (

        <div>

            <ul>

                {lessons.map(lesson => (

                    <li key={lesson.id}
                        style={{color: lessonId === lesson.id ? 'red' :

'#333'}}

                        onClick={() => setLessonId(lesson.id)}

                    >

                        {lesson.name}

                    </li>

                ))}

            </ul>

        </div>

    )

useLayoutEffect

// useeffect

// 1. Cập nhật lại state

// 2. Cập nhật lại DOM (mutated)

// 3. Render lại UI

// 4. Gọi cleanup nếu deps thay đổi

// 5. Gọi useEffect callback

// useLayoutEffect

// 1. Cập nhật lại state

// 2. Cập nhật lại DOM (mutated)

// 3. Gọi cleanup nếu deps thay đổi (sync)

// 4. Gọi useLayoutEffect callback (sync)

// 5. Render lại UI

function Content() {

    const [count, setCount] = useState(0)

    useLayoutEffect(() => {

        if(count > 3)
            setCount(0)

    }, [count])

    const handleRun = () => {

        setCount(count + 1)

    }

    return (

        <div>

           <h1>{count}</h1>

           <button onClick={handleRun}>Run</button>

        </div>

    )

useRef: Lưu giá trị qua một tham chiếu bên ngoài function component

function Content() {

    const [count, setCount] = useState(60)

    let timerId = useRef()

    const handleStart = () => {

        timerId.current = setInterval(() => {

            setCount(prevCount => prevCount -1)

        }, 1000)

        console.log('start ->',timerId.current)

    }

    const handleStop = () => {

        clearInterval(timerId.current)

        console.log('stop ->',timerId.current)
    }

   

    return (

        <div style={{padding: 20}}>

           <h1>{count}</h1>

           <button onClick={handleStart}>Start</button>

           <button onClick={handleStop}>Stop</button>

        </div>

    )

function Content() {

    const [count, setCount] = useState(60)

    const timerId = useRef()

    const prevCount = useRef()

    const h1Ref = useRef()

    useEffect(() => {

        prevCount.current = count

    }, [count])

    useEffect(() => {

        console.log(h1Ref)

    })

    const handleStart = () => {

        timerId.current = setInterval(() => {

            setCount(prevCount => prevCount -1)

        }, 1000)
        console.log('start ->',timerId.current)

    }

    const handleStop = () => {

        clearInterval(timerId.current)

        console.log('stop ->',timerId.current)

    }

    console.log(count, prevCount.current)

   

    return (

        <div style={{padding: 20}}>

           <h1 ref={h1Ref}>{count}</h1>

           <button onClick={handleStart}>Start</button>

           <button onClick={handleStop}>Stop</button>

        </div>

    )

useCallback: Giúp tránh tạo ra những hàm mới một cách không cần thiết trong function component

function App() {

  const [count, setCount] = useState(60)

  const increase = useCallback(() => {

    setCount(prevCount => prevCount + 1)

  }, [])

  return (

    <div style={{ padding: 20 }}>

      <Content onIncrease={increase}/>
      <h1 >{count}</h1>

    </div>

  )

useMemo: Giúp tránh thực hiện lại một logic nào đó không cần thiết

function App() {

  const [name, setName] = useState('')

  const [price, setPrice] = useState('')

  const [products, setProducts] = useState([])

  const nameRef = useRef()

  const handleSubmit = () => {

    setProducts([...products, {

      name,

      price: +price

    }])

    setName('')

    setPrice('')

    nameRef.current.focus()

  }

  const total = useMemo(() => {

    const result = products.reduce((result, prod) => result + prod.price, 0)

    return result

  }, [products])
  return (

    <div style={{ padding: '10px 32px' }}>

      <input

        ref={nameRef}

        value={name}

        placeholder="Enter name..."

        onChange={e => setName(e.target.value)}

      ></input>

      <br></br>

      <input

        value={price}

        placeholder="Enter price..."

        onChange={e => setPrice(e.target.value)}

      ></input>

      <br></br>

      <button onClick={handleSubmit}>Add</button>

      <br></br>

      Total: {total}

      <ul>

        {products.map((product, index) => (

          <li key={index}>{product.name} - {product.price}</li>

        ))}

      </ul>

    </div>

  )

}
useReducer: Cùng cấp cho người dùng có thêm sự lựa chọn để sử dụng state cho function
conponent

// Init State

const initState = 0

// Actions

const UP_ACTION = 'up'

const DOWN_ACTION = 'down'

// Reducer

const reducer = (state, action) => {

  console.log('reducer running...')

  switch(action) {

    case UP_ACTION:

      return state + 1

    case DOWN_ACTION:

      return state - 1

    default:

      throw new Error('Invalid action')

  }

function App() {

  const [count, dispatch] = useReducer(reducer, initState)

  return (

    <div style={{ padding: '10px 32px' }}>

      <h1>{count}</h1>

      <button

        onClick={() => dispatch(DOWN_ACTION)}

      >Down</button>
      <button

        onClick={() => dispatch(UP_ACTION)}

      >Up</button>

    </div>

  )

const intitState = {

  job: '',

  jobs: []

const SET_JOB = 'set_job'

const ADD_JOB = 'add_job'

const DELETE_JOB = 'delete_job'

const setJob = payLoad => {

  return {

    type: SET_JOB,

    payLoad

  }

const addJob = payLoad => {

  return {

    type: ADD_JOB,

    payLoad

  }

}
const deleteJob = payLoad => {

  return {

    type: DELETE_JOB,

    payLoad

  }

const reducer = (state, action) => {

  switch (action.type) {

    case SET_JOB:

      return {

        ...state,

        job: action.payLoad

      }

    case ADD_JOB:

      return {

        ...state,

        jobs: [...state.jobs, action.payLoad]

      }

    case DELETE_JOB:

      const newJobs = [...state.jobs]

      newJobs.splice(action.payLoad, 1)

      return {

        ...state,

        jobs: newJobs

      }

    default:

      throw new Error('Invalid action')

  }

  return state
}

function App() {

  const [state, dispatch] = useReducer(reducer, intitState)

  const { job, jobs } = state

  const inputRef = useRef()

  const handleSubmit = () => {

    dispatch(addJob(job))

    dispatch(setJob(''))

    inputRef.current.focus()

  }

  return (

    <div style={{ padding: '10px 32px' }}>

      <h3>Todo</h3>

      <input

        ref={inputRef}

        value={job}

        placeholder="Enter todo..."

        onChange={e => {

          dispatch(setJob(e.target.value))

        }}

      ></input>

      <button onClick={handleSubmit}>Add</button>

      <ul>

        {jobs.map((job, index) => (

          <li key={index}>
            {job}

            <span onClick={() => dispatch(deleteJob(index))}>&times;</span>

          </li>

        ))}

      </ul>

    </div>

  )

You might also like