React hooks: 04 - useState() qua ví dụ TodoList (2020)

Поделиться
HTML-код
  • Опубликовано: 9 фев 2025
  • Một ví dụ đơn giản nhưng rất chi tiết về cách sử dụng useState() hook trong functional component của react. Đây là một video trong chuỗi react hooks của mình.
    Trong video này, mình cùng code với các bạn để chia sẻ một vài ý:
    Phân tích components trước khi code.
    Sử dụng useState() để quản lý danh sách todos.
    Hướng dẫn cách render một list các items trong ReactJS.
    Hướng dẫn remove một item ra khỏi list trong ReactJS.
    🌐 Link tham khảo
    Slide useState lab: drive.google.c...
    Link source code: github.com/pau...
    Introduction to react hooks: reactjs.org/do...
    React hooks API reference: reactjs.org/do...
    React hooks FAQ: reactjs.org/do...
    #react_hooks #reactjs #usestate #easyfrontend
    -----
    💻 Easy Frontend 🎉
    Nơi kiến thức lập trình web frontend (html/css/javascript/reactjs) được chia sẻ một cách đơn giản, dễ hiểu mà đặc biệt là vui 😊 Với những tài liệu (tutorial) được biên soạn một cách kĩ lưỡng để giúp các bạn developer mới có thể nắm bắt vấn đề một cách nhanh chóng và hiệu quả. Từ đó nâng dần khả năng coding của các bạn lên theo thời gian.
    ❤️ Ủng hộ mình làm videos thì đóng góp tại đây nhé:
    Ủng hộ tôi: unghotoi.com/e...
    MoMo/ZaloPay: 0901 309 729
    Kết nối với mình:
    🎉Facebook: / nvhauesmn
    💻Github: github.com/pau...
    💼 LinkedIn: / haunguyenmn

Комментарии • 171

  • @EasyFrontend
    @EasyFrontend  4 года назад +5

    Cảm ơn các bạn đã xem video của mình!
    Hãy like, share và subscribe nếu các bạn thấy hữu ích nhé! ❤️
    Bạn nào code theo mình được thì điểm danh cho mình biết với nhé! 😉

    • @huycuongnguyen4543
      @huycuongnguyen4543 4 года назад

      em code được color box rồi anh ơi :v

    • @EasyFrontend
      @EasyFrontend  4 года назад

      Huy Cường Nguyễn =))) giờ tiếp todo list hen 😉

    • @dungduong7585
      @dungduong7585 4 года назад

      hóng anh dạy redux ạ

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Dung Duong hehe cảm ơn em nha, nó sẽ tới sớm thôi nè, do a chỉ có mỗi tối hằng ngày để làm video thôi nên ko ra nhanh được 🙂

    • @dungduong7585
      @dungduong7585 4 года назад

      @@EasyFrontend dạ. cảm ơn anh ạ

  • @phanxuanhao6190
    @phanxuanhao6190 Год назад

    Mong bạn update về khóa hoc React 2023 tren Udemy để mình đăng ký á.

    • @EasyFrontend
      @EasyFrontend  Год назад

      hi bạn, mình cũng muốn update mà do bận quá
      chắc mình sẽ tạo khóa mới luôn cho nó tiện theo dõi, cơ mà sẽ hơi lâu
      tạm thời bạn tham khảo những bên khác giúp mình nhen, cảm ơn bạn nhiều nhiều ❤️

  • @nguyentin6582
    @nguyentin6582 2 года назад

    a dạy dễ hiểu ghê

  • @channelttn9460
    @channelttn9460 3 года назад

    Anh dảng bài nói chuyện cute thật luôn giáo viên oắt trường dạy vậy chắc 10, hết luôn

    • @EasyFrontend
      @EasyFrontend  3 года назад

      haha cảm ơn em nhiều nhé, tuy nhiên anh đc cái diễn giải thôi nè, còn kiến thức thì mình nghĩ thầy giỏi và chuyên sâu hơn mình nhiều nè 😉

  • @atnguyentien8630
    @atnguyentien8630 4 года назад

    Giờ mới biết kênh của anh. Cảm ơn anh đã chia sẻ. Anh dạy dễ hiểu quá !!

    • @EasyFrontend
      @EasyFrontend  4 года назад

      wohooo cảm ơn em nhiều nhé Đạt ơi 😊

  • @ucnguyentrung1421
    @ucnguyentrung1421 3 года назад

    E mới học FE và ms bắt đầu học React xem video của a thấy hay và dễ hiểu quá =))

    • @EasyFrontend
      @EasyFrontend  3 года назад

      yeah cảm ơn em nhiều nha, kênh còn nhiều nội dung hay lắm, em có thể tham khảo nhen hehe
      www.ezfrontend.com/blog/tong-hop-tai-lieu-hay-tu-easy-frontend

  • @vuhoang4181
    @vuhoang4181 4 года назад +3

    Về phần auto Organize Imports thì VSCode nó sửa lại thành Shift + Alt + O rồi nha các bạn.

    • @EasyFrontend
      @EasyFrontend  4 года назад

      Coder Cyan Yeah cảm ơn bạn update thông tin cho mn nhé ❤️

    • @hungnguyenxuan3973
      @hungnguyenxuan3973 4 года назад

      Cảm ơn bạn vì thông tin này :D

  • @phanhaiang7052
    @phanhaiang7052 3 года назад +1

    may mắn khi được kết bạn với anh trên Facebook

  • @congloibui3363
    @congloibui3363 4 года назад +3

    function handleTodoClick có thể dùng hàm filter để viết ngắn lại thầy ah
    vd : let newTodoList = todoList.filter(item => item.id !== todo.id)

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Yeah hợp lý nha Lợi ơi, cảm ơn em nhiều nhen hehe 😉

  • @thienlynguyen5646
    @thienlynguyen5646 4 года назад

    Đang vừa ăn mì vừa cố gắng xem hết các bài giảng của anh

    • @EasyFrontend
      @EasyFrontend  4 года назад

      lol chăm học quá nè, ý mà trời đánh tránh bữa ăn, nên enjoy ăn uống xong hãy học nhen Lý 🙂

  • @LamNguyen-rc2ic
    @LamNguyen-rc2ic 3 года назад

    Video hay lắm a 🤘🤘

    • @EasyFrontend
      @EasyFrontend  3 года назад

      hehe cảm ơn em nhiều nhé Lâm 😍

  • @ngthuongnguyen9804
    @ngthuongnguyen9804 2 года назад

    A ơi đối tượng ColorBox.propTypes = {} để làm gì a nhỉ!!! :))

    • @ngthuongnguyen9804
      @ngthuongnguyen9804 2 года назад

      Có video giải thích về đối tượng này ko, a gửi link e với nhé

    • @EasyFrontend
      @EasyFrontend  2 года назад +1

      hi em, em tham khảo ở link này nhé
      reactjs.org/docs/typechecking-with-proptypes.html
      cơ bản nó giúp mình validate cái kiểu dữ liệu của props mình truyền vào em nhen hehe

    • @ngthuongnguyen9804
      @ngthuongnguyen9804 2 года назад

      E cảm ơn a nhé, e hiểu rồi

  • @vanthiennguyen1751
    @vanthiennguyen1751 3 года назад

    A ơi cho e hỏi e dùng filter thì không sao nhưng khi e thử clone mảng thì nó lại lỗi như thế này là sao ạ. TypeError: _components_TodoList__WEBPACK_IMPORTED_MODULE_2__.default is not iterable

    • @EasyFrontend
      @EasyFrontend  3 года назад

      hi Thiện, cái này có vẻ import có gì đó sai sai, em check lại thử nhen, a hk chắc lắm nhen, nếu hk đc thì chụp hình code post lên nhóm trao đổi easy frontend nhen Thiện 😉

    • @vanthiennguyen1751
      @vanthiennguyen1751 3 года назад

      @@EasyFrontend dạ vâng e cảm ơn Anh nhiều ạ

  • @huyto948
    @huyto948 3 года назад

    Dạ em có Code theo mà nó hiện lỗi ntn. Nhờ anh giúp em tí ạ
    src\Components\TodoList\index.jsx
    Line 15:19: 'onTodoCick' is assigned a value but never used no-unused-vars

    • @EasyFrontend
      @EasyFrontend  3 года назад

      à nó báo là em chưa dùng onTodoClick á Huy 😉

  • @komaiptit5792
    @komaiptit5792 2 года назад

    anh cho em hỏi là em tạo 1 file tên "todoList.js" sau đó export ra như a làm ở file "index.jsx" thì nó có khác gì nhau ko ạ, và em ko dùng PropTypes ạ

    • @EasyFrontend
      @EasyFrontend  2 года назад

      hi em, việc mình gom export vào một file index.js, nó sẽ giúp em import gọn hơn khi sử dụng
      ví dụ: import { ComponentA, ComponentB } from '@/common'
      thay vì
      import ComponentA from '@/common/ComponentA'
      import ComponentB from '@/common/ComponentB'
      khi em có càng nhiều components chung một module thì em sẽ thấy cái này tiện lợi em nhen

    • @komaiptit5792
      @komaiptit5792 2 года назад

      @@EasyFrontend anh có thể giải thích kĩ hơn được ko ạ, em vẫn chưa hiểu lắm. Tại em thấy khi em để tên file là " .jsx " hay " .js " thì kết quả giao diện vẫn như nhau , a có thể giải thích kĩ hơn về sự khác nhau giữa 2 file này ko ạ

  • @TamPham-oe2xc
    @TamPham-oe2xc 4 года назад +1

    Note cho mấy bạn ko remove đc 'Unused import' như a Hậu nói thì :
    bên Window nếu như bạn xài VSCode thì sẽ là Alt + Shift + O nhé . Hóng phần useCallback() + useMemo() quá a Hậu ơi :D

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Tâm Phạm hehe a định nói sau phần useEffect() hehe, Tâm có đang gặp vấn đề gì vs useCallback hk Tâm? 😉

    • @TamPham-oe2xc
      @TamPham-oe2xc 4 года назад

      @@EasyFrontend e nghe nói phần useCallback & useMemo có thể cải thiện performance nhưng lại không biết dùng ở đâu & lúc nào cho thích hợp? mong a giải thích hoặc cho e keyword để tìm hiểu

  • @DuongNguyen-su4qm
    @DuongNguyen-su4qm 4 года назад +2

    sao mình không dùng filter array để filter out todo cho nhanh nhỉ? bản thân filter (.map, .reduce) nó trả về 1 array mới mà.
    setTodoList(todoList.filter(td => td.id !== todo.id))

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Duong Nguyen ❤️ Yeahhh, đây cũng là một giải pháp hoàn toàn hợp lệ nhé Dương. Xét về mặt tốt hơn thì cách bạn nói nó tốt hơn nhé 👍 Cảm ơn bạn Dương đã phát hiện nhen!

    • @DuongNguyen-su4qm
      @DuongNguyen-su4qm 4 года назад

      Yea. Mình góp ý thôi. Cám ơn bạn vì nội dung video khá hay.

  • @ThacHungCoder
    @ThacHungCoder 3 года назад

    mọi người cho mình hỏi, trong thực tế mình có viết code từ bên "component todoList" rồi mới viết sang "component App" như lúc render todo ko vậy?

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      hi Hưng ơi, mình nghĩ cái này thì ko có chuẩn, chỉ là ai thuận chiều nào làm chiều đó, top-down hoặc bottom-top :)
      Top-down thì tiện hơn tí, có dữ liệu từ trên đổ xuống, khi render sửa lại UI là xong.
      Bottom-top thì nó đơn giản lúc đầu, chỉ quan tâm làm UI, lúc sau gắn logic vào là xong.
      Kiểu nào cũng đc, quan trọng là mình quen kiểu nào, xúc kiểu đó hehe

    • @ThacHungCoder
      @ThacHungCoder 3 года назад

      @@EasyFrontend em mới học react anh ạ, nên thấy anh code bottom-top thấy hay quá, ko lẽ học theo anhh ^^. mà anh rep nhanh nhỉ

  • @ogs3331
    @ogs3331 3 года назад

    Ủa mọi người, Khi xóa 1 phần tử trong cái todoList thì tại sao không xóa trực tiếp trên todoList luôn. Ví dụ: todoList.Spice(index,1)
    mà tại sao phải tạo biến newTodoList clone từ todoList rồi mới xóa.

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      hi em, với state là kiểu dữ liệu dạng tham chiếu (object, array, ...) thì khi thay đổi, em phải thay đổi tham chiếu của nó bằng cách clone từ cái cũ ra cái mới rồi thay đổi nha, nếu em thay đổi trực tiếp lên tham chiếu cũ nó sẽ ko hiểu là em có thay đổi và ko trigger re-render, em hãy thử nhé 😉

    • @ogs3331
      @ogs3331 3 года назад

      @@EasyFrontend dạ, cám ơn anh.

  • @anhphunguyen5094
    @anhphunguyen5094 3 года назад

    E đang thắc mắc dòng 28 (TodoList). Khi mình bắt sự kiện onclick gọi hàm HandleClick vì sao phải bỏ trong arrow function ạ ? Nhờ anh Hậu và mọi người giải đáp ạ !

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      em tham khảo câu trả lời này nhé Phú
      res.cloudinary.com/kimwy/image/upload/v1637369222/easyfrontend/arrow-function_kpwfaj.jpg

    • @anhphunguyen5094
      @anhphunguyen5094 3 года назад

      @@EasyFrontend Em cảm ơn anh Hậu. Kiến thức rất hữu ích ạ !!

    • @phanxuanhao6190
      @phanxuanhao6190 Год назад

      Cám ơn câu hỏi và câu trả lời, mình cũng có thắc mắc giống vậy.

  • @thinhhuynh3789
    @thinhhuynh3789 4 года назад

    Nghe anh giải thích cách dùng của onTodoClick với handleClick em mới ngộ ra, trước giờ em không biết phải xử lý khi thay đổi state ở component con như thế nào, đành dùng hạ sách là copy component con bỏ qua phần gọi luôn :D

    • @EasyFrontend
      @EasyFrontend  4 года назад

      Yeahhhh cái này gọi là đã thông kinh mạch nè hihi, ngon lành Thịnh hen hihi 😍

  • @thuan20132000
    @thuan20132000 4 года назад

    Hay lắm anh, cảm ơn anh nhé.

    • @EasyFrontend
      @EasyFrontend  4 года назад

      hihi cảm ơn e nhiều nhé Thuận ❤️

  • @noras9835
    @noras9835 4 года назад +1

    Để xóa những dòng không sử dụng bên Window theo mặc định là Shift + Alt + o anh nha!

    • @EasyFrontend
      @EasyFrontend  4 года назад

      à vậy hở, cảm ơn e nha. A hk dùng windows, cứ ngỡ nó map 1-1 qua chứ 😅

    • @noras9835
      @noras9835 4 года назад

      hihi mà map 1-1 là gì vậy anh ?

    • @EasyFrontend
      @EasyFrontend  4 года назад

      Noras ah hihi, ý anh là nó map tương ứng phím này bên macos sẽ là 1 phím bên windows. Như Option bên mac sẽ là Alt bên windows chẳng hạn 🙂

    • @noras9835
      @noras9835 4 года назад

      Dạ hihi

    • @TamPham-oe2xc
      @TamPham-oe2xc 4 года назад

      Bên Window nếu như bạn xài VSCode thì sẽ là Alt + Shift + O. nhé

  • @nghiahohieu7172
    @nghiahohieu7172 3 года назад

    a ơi làm thế nào để sử dụng được chức năng auto import thế ạ? e mò thử mãi nhưng k đc

    • @EasyFrontend
      @EasyFrontend  3 года назад

      à cái đó thì nó tự có em nha, nếu ko đc thì em thử cái thêm Auto Import extension thử nha 😉

  • @hungvan6232
    @hungvan6232 4 года назад

    thầy ơi, em bị lỗi chỗ nào mà cứ click bất cứ item nào thì nó xoá cứ mặc định xoá id theo thứ tự 1-2-3 ạ.

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi Hùng, em post lên group facebook nha hehe 😉Chứ ở đây hk biét em code sao nên anh hk rõ nữa nè 😉

    • @hungvan6232
      @hungvan6232 4 года назад

      @@EasyFrontend dạ, tại em nhìn đề thầy cho xong tự nghĩ code rồi,code không ra rồi mới nhìn code thầy, mà khi code lại theo thầy thì e thấy vẫn như cũ. để em thử code lại theo thầy lần nữa xem sao

    • @hungvan6232
      @hungvan6232 4 года назад

      @@EasyFrontend em làm lại được rồi thầy ơi, em sai chỗ này 'onClick={()=>handleClick(todo) ' em truyền thẳng cái {handleClick} như thế này nên bị sai ạ.

  • @vutruongsinh3591
    @vutruongsinh3591 3 года назад

    anh ơi, sao mình phải cần 1 hàm handleClick chỉ để gọi lên thằng onTodoClick(todo), trong khi đó mình code thẳng onClick={() => onTodoClick(todo) luôn vậy anh?

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      à cái này cũng được em nha, nhưng lưu ý giúp anh check thêm onTodoClick ko bị undefined nhen, nếu ko em gọi onTodoClick() sẽ bị lỗi á.
      Mục đích việc gọi hàm cũng là để handle mấy cái logic này riêng, khỏi để trên jsx rườm rà thôi à hehe
      Em có thể đổi thành thế này nha Vũ: onClick={() => onTodoClick && onTodoClick(todo)}

    • @vutruongsinh3591
      @vutruongsinh3591 3 года назад

      @@EasyFrontend Dạ em cảm ơn anh! em "tay ngang" bay qua học lập trình, nhờ có kênh của anh mà em ngộ ra rất nhiều điều....

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      @@vutruongsinh3591 Yeah hay quá Vũ ơi, a rất vui khi biết đc nội dung có ích được cho em nè 😍, hi vọng sẽ giúp ích đc chút xíu nào đó cho công việc và học tập của em hihi

  • @huy19437
    @huy19437 3 года назад

    vì sao chỗ onClick trên thẻ li anh lại dùng arrow func vậy ạ, nó khác gì khi anh gọi handleClick(todo) ạ

    • @EasyFrontend
      @EasyFrontend  3 года назад +2

      cái này anh có trả lời cho nhiều bạn rồi, em tham khảo lại nha. Anh copy bên dưới.
      -----
      hi anh Hậu ạ, anh cho em hỏi chút là khi nào mình truyền vào 1 hàm và khi nào thì mình gọi một hàm ạ
      VD: onClick={handleTodo}
      onClick ={() => console.log('Hello')}
      ----
      Trả lời:
      hi Tuấn, cả 2 đều là truyền vào hàm, ko có cái nào là gọi hàm hết em nha
      onClick={handleTodo} : cái này là truyền vào một tham chiếu hàm
      onClick ={() => console.log('Hello')}: cái này là truyền vào một hàm mà hàm này được tạo ra khi gọi, mình gọi nó là inline function
      cả 2 trường hợp này đều truyền vào function, ko có cái nào là gọi hàm nha em
      ---
      tiếp đến là khi nào dùng cái nào
      Cách 1:
      - Tham chiếu tạo ra một lần và mỗi lần click thì gọi tới tham chiếu đó thôi.
      --> Nên dùng cách này khi có thể
      Cách 2:
      - Mỗi lần click là nó sẽ tạo ra một hàm mới rồi mới thực thi (tham chiếu đc tạo ra mỗi lần click)
      - Hạn chế sử dụng, nhưng vẫn có trường hợp buộc sử dụng là truyền tham số tuỳ biến vào hàm.
      Ví dụ handleTodo() cần em truyền vào biến todo thì buộc phải dùng inline òi, tại hàm onClick ko cho em todo, em phải lấy chỗ khác truyền vào.
      ```js
      function App() {
      const [todoList, setTodoList] = useState([])
      // ví dụ hàm này cần nhận vào todo
      const handleTodo = (todo) => {}
      // vậy làm sao truyền todo vào hàm handleTodo bây giờ, onClick thì nó cung cấp biến e: Event,
      // chứ đâu có todo, nên buộc phải dùng inline function chỗ này òi
      return (
      {todoList.map(todo => (
      handleTodo(todo)}>{todo.content}
      ))}
      )
      }
      ```

    • @huy19437
      @huy19437 3 года назад

      @@EasyFrontend cảm ơn anh nhiều ạ

  • @baotrietle3570
    @baotrietle3570 3 года назад

    Mình có thắc mắc là tất cả business logic của Todo item onlick có nên để dành riêng cho Todo Component xử lý hay không vì mình thấy App có hàm handleClick của Todo thấy nó bị phụ thuộc vào App quá nếu muốn sử dụng TodoList component qua project khác thì không làm dc với lại khi App gắn nhiều component con lên thì số lượng hàm sẽ nhiều và khó quản lý nếu để chung.

    • @EasyFrontend
      @EasyFrontend  3 года назад

      hi Bảo, ở đây có một số ý nhen:
      1. Mình prefer tạo ra các dump/ui component hơn là smart/stateful component để có thể tái sử dụng ở nhiều nơi khác nhau.
      2. Có nên đẩy logic lên App ko? À thật ra thì ko, thường logic sẽ được handle ở cái trang chứa các component này, chứ ko phải là đẩy lên App. Tại ở đây ko làm routings, nên lấy App làm trang chứa mấy components này thôi nè. 🙂

  • @hatuyen8856
    @hatuyen8856 4 года назад

    Anh ơi. sao e để
    const newArray = [...todoList];
    setTodoList(newArray.splice(index, 1)); => result lỗi dạ anh
    còn e dùng cách filter thì result ra
    const newArray = [...todoList];
    setTodoList(newArray.filter(item => item.id !== todo.id));

    • @EasyFrontend
      @EasyFrontend  4 года назад

      Hà Tuyền Hi Tuyền ơi, chỗ setTodoList bạn làm chưa đúng nè. Hàm Splice nó sẽ trả về cái mảng chứa các phần tử bị remove, chứ hk phải là mảng hiện tại sau khi remove nhé.
      Bạn đọc tham khảo thêm ở đây hen developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
      Còn về cách xài filters là hoàn toàn hợp lệ nha Tuyền ơi! 🙂

    • @hatuyen8856
      @hatuyen8856 4 года назад

      @@EasyFrontend dạ, oke tks anh

    • @trandoan4526
      @trandoan4526 3 года назад

      Mình nghĩ dùng filter thì không cần clone 1 mảng mới ra vì bản thân thằng filter đã tạo ra 1 mảng mới rồi

  • @TienBui-ot5pd
    @TienBui-ot5pd 3 года назад

    Hi Anh. Cho em hỏi xíu vd trong trường hợp là . Có 1 page gồm 2 input và 1 button search. Nếu nhấn vào search thì call API lấy data Còn ko nhấn vào button thì ko hiên thị data.
    Ý tưởng là
    Sẽ có 2 state 1state filter là chứa 2 input search
    1 state sẽ chứa data sau khi call API
    1 effect có dependency filter thấy đổi thì sẽ chạy effect call API
    Do useEffect lần đầu tiên nó vẫn chạy nên sẽ check thêm if filter.name || filter.email thì mới call API else ko call API
    Khi click button search thì sẽ set state filter thôi.
    Thường là như vậy phải ko Anh

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      yeah đúng òi nha Tiến ơi 😉

  • @trieuthuan8995
    @trieuthuan8995 4 года назад

    Cảm ơn A Hậu

    • @EasyFrontend
      @EasyFrontend  4 года назад

      hihi cảm ơn e nhé ❤️. Em có code theo được đươc hk Thuận? 🙂

    • @trieuthuan8995
      @trieuthuan8995 4 года назад

      @@EasyFrontend Dạ được anh !! Anh Hậu hướng dẫn quá chi tiết luôn mà hihii

  • @confessionspp3725
    @confessionspp3725 3 года назад

    Anh ơi mình dùng axios để remove 1 item, thì mình todoApi.remove(todo.id) là được đúng không anh (em làm như này vẫn chạy được), không cần phải truyền index

    • @EasyFrontend
      @EasyFrontend  3 года назад

      à em gọi API thì cần ID như vậy là đủ rồi em nhen, ko cần index nhé hehe
      Sau khi gọi remove api xong thì em gọi lại API list để nó fetch list mới về là okie nhen hehe

    • @confessionspp3725
      @confessionspp3725 3 года назад

      @@EasyFrontend tks anh

  • @laptrinhwebcungnhauhoc
    @laptrinhwebcungnhauhoc 3 года назад

    tại sao mình không viết tất cả ở file Component , mà phải truyền qua truyền lại vậy anh

    • @mersy4405
      @mersy4405 3 года назад

      cho dễ quản lý thôi bạn, dự án thực tế sẽ có nhiều feature nên chia ra cho dễ

  • @ziwok5831
    @ziwok5831 3 года назад

    Em có một thắc mắc là sao k thêm 1 tham số là idx ở hàm map nữa, khi onClick thì mình xóa trực tiếp idx đó luôn đỡ phải mất công đi tìm :v

  • @DungVan-uk6vg
    @DungVan-uk6vg 3 года назад

    Ah ơi cái chỗ tìm index thì mình chỉ cần const index=todo.id là được mà ah nhỉ đâu cần dùng hàm findIndex đâu ạ :)

    • @EasyFrontend
      @EasyFrontend  3 года назад

      lol làm sao đc em ơi, ở đây vô tình anh chỉ để id là 1, 2, 3 ví dụ thôi, chứ id thật đâu có vậy =))) với chưa kể nó còn thay đổi nữa nha Dũng

    • @trandoan4526
      @trandoan4526 3 года назад

      @@EasyFrontend Anh ơi đoạn đó em dùng thế này vẫn ra liệu có được không ạ
      const newItem = todoList.filter((p) => p.id !== todo.id);
      setTodoList(newItem);

    • @EasyFrontend
      @EasyFrontend  3 года назад

      @@trandoan4526 à được em nhé, mình dùng cách này khi ko biết index của item cần remove.
      Còn khi đã biết index thì dùng cách của anh cho lẹ nhen 😉

  • @tunguyenanh1279
    @tunguyenanh1279 4 года назад

    Dạ a ơi cho em hỏi khi nhấn ul.todo-list rồi tab ra thì nó sẽ tự động ra thẻ ul có class là dùng extension gì v a. Em dùng ko đc ạ

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi Tú ơi, để gõ được cái đó, em có thể gõ trong:
      1. File HTML
      2. File JS, mà để ý góc dưới bên trái, mình chọn ngôn ngữ Javascript React nha
      🙂

  • @glorynt7925
    @glorynt7925 4 года назад

    có thể giải thích cái propTypes được không ạ. no có tác dụng gì. và defaulPropType nữa tại vì mấy bài trước không thấy a có nhắc nên hơi không hiểu

    • @EasyFrontend
      @EasyFrontend  4 года назад +11

      hi Glory,
      1. PropTypes là thư viện giúp em check props đầu vào của component phải đúng kiểu dữ liệu em khai báo. Nếu ko đúng nó sẽ báo lỗi cho em, để em sửa lại cho đúng.
      2. Default props là khi một prop ko required, thì buộc phải có default value. Vd user ko truyền props A thì em muốn xài giá trị mặc định nào cho props A đó 🙂
      3. Vụ props types nó chỉ giúp em dưới local, phát hiện bugs sớm và xử lý nè 🙂
      4. Ko khai báo props types nó vẫn chạy bình thường, nhưng nếu e truyền sai kiểu dữ liệu nó cũng ko báo lỗi cho em.
      5. Thực tế là khuyến khích em nên dùng nhé vì những tác dụng đề cập ở trên, đồng thời em cũng biết component đó sử dụng những props gì, ko thôi em phải đọc hết code mới biết đc nó dùng những props gì 😎
      Hi vọng là trả lời được thắc mắc của em 🙂

  • @user-gi1kx4zt5o
    @user-gi1kx4zt5o 4 года назад

    Anh ơi cho em hỏi là mình sử dụng hook cho toàn bộ project react native đc không anh

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi em ơi, a chưa làm với React Native nhiều, nên hk dám trả lời câu hỏi của em nè hihi

    • @user-gi1kx4zt5o
      @user-gi1kx4zt5o 4 года назад

      @@EasyFrontend Dạ em cảm ơn anh nha...Coi như luận văn kì này toang rồi anh ơi 🙉

  • @nguyencanhtrung
    @nguyencanhtrung 4 года назад

    Em không ctrl + option + o để tối ưu import được a ơi? cái short key này là do plugin nào của VS a nhỉ ?

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      nguyen canh trung hi Trung, em dùng Mac thì thử Shift Option O thử sao nhen 😉 Nếu ko đc e tìm từ khoá organize import trong vscode nha 🙂

    • @nguyencanhtrung
      @nguyencanhtrung 4 года назад

      @@EasyFrontend Shift Option O là chuẩn rồi a ạ

  • @DungNguyen-sq6sy
    @DungNguyen-sq6sy 3 года назад

    .

  • @quylecao2743
    @quylecao2743 4 года назад

    anh giải thích thêm về cái check propsTypes được không ạ.nó có tác dụng gì. vô dự án thực tế khi đi làm có cần phải check không. tại em thấy hơi thừa?

    • @EasyFrontend
      @EasyFrontend  4 года назад +5

      quy le cao Hi Quý, có một vài điểm mình nghĩ thế này:
      1. PropTypes nó giúp bạn kiểm tra đúng loại dữ liệu khi dev. Bạn hãy thử thế này, khai báo object, mà truyền vào array xem sao. Lúc chạy lên nó sẽ báo lỗi ở console, điều này giúp mình phát hiện lỗi sớm.
      2. Bạn nên có props, thỉnh thoảng bạn muốn biết component này có những props gì? Bạn làm thế nào? À vào code đọc nè. Nhưng nếu có phần khai báo này, bạn hoàn toàn có thể thấy đc ngay các props được dùng và giá trị mặc định của nó. 🙂
      Đó là suy nghĩ của mình.
      Hi vọng giải đáp đc thắc mắc của bạn! 🙂

  • @nambui526
    @nambui526 4 года назад

    cảm ơn a ạ

    • @EasyFrontend
      @EasyFrontend  4 года назад

      nam nam hihi cảm ơn Nam, e code theo được hk Nam?

  • @vantungpham159
    @vantungpham159 3 года назад

    a ơi e làm theo a rồi bị lỗi e search gg rồi mà ko dc ! help em với ! thank a

    • @EasyFrontend
      @EasyFrontend  3 года назад

      em bị lỗi gì vậy Tùng, em tổng hợp thông tin rồi post lên group fb để mn support em nha 😉

  • @TrangHuyen-vk1qe
    @TrangHuyen-vk1qe 3 года назад

    Dự án thực tế anh nói là trong khóa học react trên udemy phải k ạ? Hiện tại e mới thấy a update tới bài shopping cart trên udemy

    • @EasyFrontend
      @EasyFrontend  3 года назад +1

      hi Trang, cái shopping cart đó là phần dự án thực tế á em nhen hihi, a sẽ chỉ mọi người tổ chức từng module một trong dự án thực tế, xong sau đó apply vào xây dựng cái shopping card đó nhen 😉

    • @TrangHuyen-vk1qe
      @TrangHuyen-vk1qe 3 года назад

      @@EasyFrontend à, do em chưa có tiền đăng ký học nên hay vào udemy tham khảo lộ trình thôi anh :v

    • @TrangHuyen-vk1qe
      @TrangHuyen-vk1qe 3 года назад

      @@EasyFrontend sắp tới a dự định up lên về chủ đề gì của khóa học nhỉ, khi nào có tiền mua ủng hộ anh :v

  • @tradertieuhoc9398
    @tradertieuhoc9398 4 года назад

    Anh ơi tầm 8:31 ạ. Cái chỗ key = {todo.id}.
    Em viết giống anh thì ở console nó hiện lên 1 cái error như này:
    Warning: Encountered two children with the same key, `2`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted - the behavior is unsupported and could change in a future version.
    Anh làm ơn giải thích giúp em với ạ ???
    À em sửa thành
    todos.map((todo, index) => (
    )
    Thì hết lỗi ạ

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Nam Anh Phạm hi Anh, cái này là do một trong 2 lý do:
      - Cái key bị trùng, tức todo.id bị trùng.
      - Hoặc key bị null/undefined, em xem lại dữ liệu thử nhen hehe 😉

    • @tradertieuhoc9398
      @tradertieuhoc9398 4 года назад

      @@EasyFrontend Ui chuẩn luôn anh ơi. Em nhập bị trùng 1 cái id. Cảm ơn anh nhiều ạ !!!

    • @hifanci2506
      @hifanci2506 3 года назад

      nó ghi rõ ràng là 2 thằng nhỏ trùng key `2` luôn á @@

  • @thanhdungnguyen6953
    @thanhdungnguyen6953 4 года назад

    Để xóa 1 item e làm theo cách này được k ạ,
    function handleRemoveItem(id) {
    const newTodos = todos.filter((todo) => todo.id !== id);
    setTodos(newTodos);
    }
    a có thể giải thích nên dùng cách như a hay là cách e làm ạ, vì trước giờ e xử lý xóa 1 item toàn như này.

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi Dũng, cả 2 cách điều được nha em.
      Còn xài cái nào thì tuỳ tình huống nè.
      Nếu biết index thì xoá kiểu anh cho gọn.
      Nếu ko biết index mà biết id thì xoá như em sẽ tốt hơn.
      Nên linh hoạt sử dụng nhen Dũng 🙂

    • @thanhdungnguyen6953
      @thanhdungnguyen6953 4 года назад

      @@EasyFrontend Dạ ok a, e cám ơn ạ

  • @nothinginyoureyes6869
    @nothinginyoureyes6869 4 года назад

    anh cho em hỏi "function handleTodoClick(todo)" ở App tại sao truyền tham số todo mà vẫn hiện ra todoList vậy ạ? em cảm ơn

    • @EasyFrontend
      @EasyFrontend  4 года назад

      hi Quang, xin lỗi là a chưa hiểu câu hỏi của em nè?
      Việc cái hàm đó là để handle lúc click lên một todo.
      Còn việc render cái todo list là riêng nè 🙂

  • @caocuong9280
    @caocuong9280 4 года назад

    A ơi. S lại đuôi file index. Jsx . E thấy họ đều để đuôi js .

    • @EasyFrontend
      @EasyFrontend  4 года назад +6

      cao cuong hi Cường ơi, hiện thì e dùng đuôi .js hay .jsx đều được nhé.
      js: em chỉ định là file javascript
      jsx: em chỉ định là file JSX, mà component của mình thì chính xác là JSX, khúc return trong component có html vs js trộn với nhau là JSX đó Cường.
      Nên a khuyên dùng jsx hơn nhen.
      Đó là ý kiến của anh thôi nha.
      Nếu e thích để js thì cứ để nè 🙂

  • @luuthevinh4048
    @luuthevinh4048 4 года назад

    khi anh tạo thằng newTodoList bằng cách copy thằng todoList thì khi xóa thằng newTodoList, thằng todoList cũng bị thay đổi theo mà. Em nghĩ như thế thì việc copy này vô nghĩa.

    • @EasyFrontend
      @EasyFrontend  4 года назад

      hi Vinh, em hãy thử dưới local và xem thử nó có works ko nhé 😉

    • @luuthevinh4048
      @luuthevinh4048 4 года назад

      @@EasyFrontend ý em muốn hỏi là ý nghĩa của việc copy newTodoList = [...todoList] ấy anh

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      @@luuthevinh4048 À khi em làm việc với state trong reactjs thì em phải đảm bảo là immutable, tránh mutate trực tiếp lên state hiện tại, nó sẽ ko works.
      Tức em đang có mảng A, em thay đổi trực tiếp lên mảng A, reactjs kiểm tra thấy ref của A cũ với A mới giống nhau --> ko render lại.
      Tuy nhiên nếu em có mảng A, e muốn thay đổi nó, em clone ra mảng mới, lúc này cái ref mới của mảng A được tạo ra, khi đó reactjs nó mới hiểu và render cái A mới cho mình.
      Tương tự khi làm việc với Redux cũng vậy nha Vinh 😉

    • @luuthevinh4048
      @luuthevinh4048 4 года назад

      @@EasyFrontend thanks anh

  • @Progamer-hs8kw
    @Progamer-hs8kw 4 года назад

    anh ơi cho e hỏi sao e cài simple react snippets rồi mà k dùng đc lệnh rsfp vậy ạ.

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      tu tran có khi nào mấy chậm ko ta? em gõ xong đợi một chút xíu xem nó có nhắc ko nhé Tú 🙂

  • @TienNguyen-vu3xv
    @TienNguyen-vu3xv 3 года назад

    Anh ơi, do đề bài yêu cầu "Render danh sách todos với dữ liệu được truyền từ component cha" nên mình mới lưu state ở App Component, lúc này gọi là global state đúng không anh?. Nếu không có yêu cầu đề bài thì em lưu state ở TodoList Component, không cần truyền props từ App xuống, giống bài ColorBox anh đã chỉ ạ. Anh ơi trong thực tế thì nên dùng cách nào ạ? Em cảm ơn anh nhiều ạ!

    • @EasyFrontend
      @EasyFrontend  3 года назад +3

      hi Tiến, trong thực tế mình luôn ưu tiên UI component nhen em.
      Tức nó chỉ nhận dữ liệu từ props và render UI tương ứng, để tăng tính tái sử dụng và hạn chế số nơi can thiệp vào app logic.
      Ở đây anh để state trên App vì cái này làm demo, chứ còn thực tế trên App chỉ chứa routings tới các features/pages thôi em nhen.
      Ví dụ TodoList của mình, em mà đưa dữ liệu vào trong là nó sẽ ko linh hoạt được, dữ liệu bị cố định.
      Còn ví dụ anh có page 1 list todo 1
      page 2 show list todo 2
      thì em đâu làm đc hen?
      Cho nên hãy để TodoList nhận props dữ liệu từ thằng cha, nó cho gì render đó hehe
      Nó ko quan tâm dữ liệu đó từ đâu, cha nó là ai, miễn cho đúng props yêu cầu là render thôi em nhen 😉

    • @TienNguyen-vu3xv
      @TienNguyen-vu3xv 3 года назад

      @@EasyFrontend Dạ em đã hiểu rồi ạ, anh giải thích rất dễ hiểu và chi tiết ạ, em rất thích xem video của anh ạ. Dạ em cảm ơn anh nhiều ạ, em chúc anh thật nhiều sức khỏe, có thêm nhiều video hay hơn nữa ạ.

  • @phucminh7985
    @phucminh7985 4 года назад

    dạ a cho e hỏi là thay vì mình truyền todo ra ngoài App thì mình có thể truyền index ra ngoài App. Tại sao a hông làm như vậy? có lí do gì hả a?? E cảm ơn a

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Phúc Minh Hay quá Phúc, bạn đã phát hiện được vấn đề rồi đó.
      Thông thường khi làm delete mình sẽ hay truyền index để remove cho lẹ. Và trong ví dụ này mình hoàn toàn có thể truyền thêm index để làm nhé!
      Nhưng ở đây mình muốn demo cho các bạn một vài ý:
      1. Ông todo list, ổng chỉ biết khi có todo đc click thì báo lên. Chứ hk biết là sẽ làm việc gì. Nên có thể một vài trường hợp mình hk có truyền index.
      2. Trong trường hợp hk biết index, có cách nào vẫn remove được todo hay ko? Yeah vẫn làm được tốt nè.
      Hi vọng giải đáp được thắc mắc của bạn. Nhưng cái bạn phát hiện là đúng rồi đó Phúc hehe ❤️

    • @phucminh7985
      @phucminh7985 4 года назад

      @@EasyFrontend Vâng a e đã hiểu hihi . Lại hóng video của a típ rùi hehe

  • @nhutle3924
    @nhutle3924 4 года назад

    này cho nhanh anh: const newTodoList = todos.filter(x => x.id !== todo.id);

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Yeahhh hoàn toàn hợp lý nhé Nhựt 😉

  • @kenindastu
    @kenindastu 4 года назад

    Cho em hỏi nếu mình chuyển dữ liệu từ App vào trong TodoList component luôn thì sao anh ?

    • @EasyFrontend
      @EasyFrontend  4 года назад +3

      Hi Ken, nếu bạn chuyển dữ liệu trực tiếp vào TodoList thì bạn sẽ khó tái sử dụng lại được nè.
      Ví dụ: HomePage muốn dùng TodoList chỉ show 6 items
      ShopPage muốn show 12 items.
      ...
      Mỗi trang có một nhu cầu show khác nhau, vậy bạn làm như thế nào?
      Với nó còn có thể dính tới filters, pagination, ...
      Nên nếu bạn đặt dữ liệu vào TodoList luôn thì coi như nó cứng ngắt ở đó, tất cả các nơi phải dùng chung giống như vậy.
      Hi vọng giải đáp được thắc mắc của bạn 🙂

    • @DungNguyen-sq6sy
      @DungNguyen-sq6sy 3 года назад

      @@EasyFrontend e vừa định hỏi, mà thấy a tl rõ ràng quá rồi :D

  • @nhatnguyentruong9960
    @nhatnguyentruong9960 4 года назад

    anh ơi cho em hỏi phím t anh nói là ctrl+alt+O hả anh mong anh trả lời em cảm ơn anh

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi Trường, cái tổ hợp phím để tổ chức import trong vscode là:
      - Windows: Shilf + Alt + O
      - MacOS: Ctrl + Options + O
      🙂

  • @antruong4836
    @antruong4836 4 года назад

    thanks anh ^^!

  • @chuucminh1124
    @chuucminh1124 4 года назад

    Bài này khi em map thằng todos em truyền thêm index khi map cho function handleClick(todo, index) thì khi bên thằng cha e lấy luôn được index ko cần dùng thằng findIndex để tìm index của phần tử trong mảng nữa. vậy tối ưu hơn a nhỉ :D

  • @khailam7681
    @khailam7681 4 года назад

    Khi nào mới đến redux với routing vậy a :D

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Khải Lâm hêh chắc phải tuần sau nữa á Lâm ơi! Tuần sau thì a sẽ nói nhiều về useEffect() hehee 😉

    • @dungduong7585
      @dungduong7585 4 года назад

      @@EasyFrontend chuẩn anh ơi, bọn em mới học nên anh dạy redux là hợp lý á

  • @daodevkidieu2022
    @daodevkidieu2022 4 года назад

    suck an amazing course !!! thank you so much, Can you help me how to use "ul.todo" and it became the ul tag with todo class?

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      Lâm Nguyễn à Lâm ơi, em dùng vscode nha, tắt chế độ gõ tiếng Việt, rồi gõ trong file html, ul.todo rồi nhấn tab nha Lâm hehe 😊

  • @trongnguyenduy3936
    @trongnguyenduy3936 3 года назад

    cảm ơn a

  • @miendongthao
    @miendongthao 4 года назад

    anh ơi, ở trong component TodoList. Chỗ event onClick tại sao mình phải viết onClick={() => handleTodoClick(todo)} mà không viết là onClick={handleTodoClick(todo)}.
    Nếu không có "() =>" thì vừa vào nó sẽ log ra hết cả 3 items luôn. Tại sao lại vậy ạ, mình đã click nó đâu và sự khác biệt ở đây là gì? Cám ơn anh

    • @EasyFrontend
      @EasyFrontend  4 года назад +1

      hi Trực ơi, hai cái này nó khác nhau nhé
      onClick={() => handleTodoClick(todo)}
      () => handleTodoClick(todo): đây là một anonymous function, trong function này chỉ có một dòng code là handleTodoClick(todo).
      Như vậy khi click, một hàm anonymous được tạo ra và thực thi hàm này.
      onClick={handleTodoClick(todo)}
      còn trường hợp này handleTodoClick(todo) là một lời gọi thực thi hàm và trả về kết quả gán về onClick.
      Như vậy ko đúng, vì onClick cần nhận vào một function nha. 😉

    • @khanhhq2044
      @khanhhq2044 3 года назад

      a cho em hỏi vậy giữa 2 thằng này có khác nhau không ạ?
      onClick={handleTodoClick} và onClick={ hanldeTodoClick() }

    • @hungnguyenmanh5333
      @hungnguyenmanh5333 3 года назад

      @@khanhhq2044 hóng a Hậu rep ạ