Immutable JavaScript Data Structures with Immer

بواسطة: egghead.io

Overview

Using immutable data structures provides many benefits, including making your code easier to reason about and less prone to bugs.
However, since JavaScript doesn't include support for immutable data structures out of the box, you need to use a third party library. But which one to choose?
In this self-paced workshop, Immer's creator Michel Westrate will guide you through the creation of a multi-user Gift Tracking app.
You'll learn the basics of using Immer to handle immutable state updates, then go further into change distribution and implementing an undo/redo.
After this workshop, you'll be ready to leverage immutable data structures in your own applications!

Syllabus

  • Introduction to the in-depth Immer course
  • Capture Application Logic in Pure Functions to Create Immutable State
  • Simplify Deep State Updates using Immer produce
  • Render Immutable Data using React
  • Profile React Rendering and Optimize with memo to Leverage Structural Sharing
  • Simplify Immer Producer Functions using Currying
  • Produces Immutable Data and Avoid Unnecessary Creation of New Data Trees with Immer
  • Immutable Update State inside React components with useImmer
  • Return Completely New State from an Immer Producer
  • Avoid Accidental Returns of New State by using the void Keyword
  • Write Asynchronous Producers in Immer and Why You Shouldn’t
  • Type Immutable Immer Data with TypeScript
  • Update Immutable State with React useReducer through Immer
  • Capture Patches to Distribute Changes in App State with Immer produceWithPatches
  • Create a Simple WebSocket Server to Distribute Patches from Immer
  • Apply Patches using Immer applyPatches to Synchronize State across Clients
  • Create Stable Patches in Immer by updating with Id instead of Indices
  • Compress the Immer Patch History by Replaying Patches on a setInterval
  • Use Immer inversePatches to Build Undo Functionality
  • Use Immer Patches to Build Redo Functionality

Taught by

Michel Weststrate

Immutable JavaScript Data Structures with Immer
الذهاب الي الدورة

Immutable JavaScript Data Structures with Immer

بواسطة: egghead.io

  • egghead.io
  • مجانية
  • الإنجليزية
  • متاح شهادة
  • متاح في أي وقت
  • الجميع
  • N/A
8.1.2PHP Version895msRequest Duration2MBMemory UsageGET ar/الدورات/{slug}Route
    • Booting (572ms)
    • Application (320ms)
    • 1 x Booting (63.94%)
      571.97ms
      1 x Application (35.82%)
      320.42ms
      14 templates were rendered
      • public.courses.show (resources/views/public/courses/show.blade.php)3bladefile
        Params
        0
        course
        1
        links
        2
        config
      • public.courses.partials.breadcrumbs (resources/views/public/courses/partials/breadcrumbs.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.heading (resources/views/public/courses/partials/heading.blade.php)7bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        classes
      • public.courses.partials.details (resources/views/public/courses/partials/details.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.breadcrumbs (resources/views/public/courses/partials/breadcrumbs.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.courses.partials.heading (resources/views/public/courses/partials/heading.blade.php)7bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        classes
      • public.layouts.main (resources/views/public/layouts/main.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.layouts.partials.meta (resources/views/public/layouts/partials/meta.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.layouts.partials.navbar (resources/views/public/layouts/partials/navbar.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.auth.profile.partials.links (resources/views/public/auth/profile/partials/links.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.auth.profile.partials.link (resources/views/public/auth/profile/partials/link.blade.php)8bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
        6
        route
        7
        title
      • public.layouts.partials.flash-session (resources/views/public/layouts/partials/flash-session.blade.php)6bladefile
        Params
        0
        __env
        1
        app
        2
        errors
        3
        course
        4
        links
        5
        config
      uri
      GET ar/الدورات/{slug}
      middleware
      web, localize:ar
      controller
      App\Http\Controllers\CourseController@show
      as
      ar.courses.show
      namespace
      prefix
      /ar
      where
      file
      app/Http/Controllers/CourseController.php:17-35
      6 statements were executed10.59ms
      • select * from `courses` where `slug_ar` = 'immutable-javascript-data-structures-with-immer' limit 1
        9.22ms/app/Http/Controllers/CourseController.php:20corspedia
        Metadata
        Bindings
        • 0. immutable-javascript-data-structures-with-immer
        Backtrace
        • 17. /app/Http/Controllers/CourseController.php:20
        • 18. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 19. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 20. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • update `courses` set `visitors` = `visitors` + 1, `courses`.`updated_at` = '2025-06-10 17:03:24' where `id` = 1728
        500μs/app/Http/Controllers/CourseController.php:21corspedia
        Metadata
        Bindings
        • 0. 2025-06-10 17:03:24
        • 1. 1728
        Backtrace
        • 17. /app/Http/Controllers/CourseController.php:21
        • 18. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 19. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 20. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select `id`, `name_en`, `name_ar`, `topic_id`, `slug_en`, `slug_ar` from `subjects` where `subjects`.`id` in (6)
        220μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 20. /app/Http/Controllers/CourseController.php:23
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 22. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 23. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 24. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select `id`, `name_en`, `name_ar`, `slug_en`, `slug_ar` from `topics` where `topics`.`id` in (1)
        180μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 25. /app/Http/Controllers/CourseController.php:23
        • 26. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 27. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 28. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 29. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select * from `providers` where `providers`.`id` in (29) and `providers`.`deleted_at` is null
        220μs/app/Http/Controllers/CourseController.php:23corspedia
        Metadata
        Backtrace
        • 20. /app/Http/Controllers/CourseController.php:23
        • 21. /vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
        • 22. /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:43
        • 23. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:260
        • 24. /vendor/laravel/framework/src/Illuminate/Routing/Route.php:205
      • select * from `html_files` where `html_files`.`id` = 1719 limit 1
        250μs/app/Models/Course.php:84corspedia
        Metadata
        Bindings
        • 0. 1719
        Backtrace
        • 21. /app/Models/Course.php:84
        • 28. view::public.courses.show:29
        • 30. /vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:125
        • 31. /vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php:58
        • 32. /vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php:72
      App\Models\HtmlFile
      1
      App\Models\Provider
      1
      App\Models\Topic
      1
      App\Models\Subject
      1
      App\Models\Course
      1
        _token
        LbUICQj6kpwbV3MxhdjvrWCvgwwDYrbwWoJCfRyR
        locale
        ar
        _previous
        array:1 [ "url" => "https://www.corspedia.com/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/immuta...
        _flash
        array:2 [ "old" => [] "new" => [] ]
        PHPDEBUGBAR_STACK_DATA
        []
        path_info
        /ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/immutable-javascript-data-structures-with-immer
        status_code
        200
        
        status_text
        OK
        format
        html
        content_type
        text/html; charset=UTF-8
        request_query
        []
        
        request_request
        []
        
        request_headers
        0 of 0
        array:24 [ "cf-ipcountry" => array:1 [ 0 => "US" ] "cf-connecting-ip" => array:1 [ 0 => "216.73.216.54" ] "cdn-loop" => array:1 [ 0 => "cloudflare; loops=1" ] "x-forwarded-proto" => array:1 [ 0 => "https" ] "x-forwarded-for" => array:1 [ 0 => "216.73.216.54" ] "sec-fetch-site" => array:1 [ 0 => "none" ] "accept" => array:1 [ 0 => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" ] "user-agent" => array:1 [ 0 => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)" ] "upgrade-insecure-requests" => array:1 [ 0 => "1" ] "sec-ch-ua-platform" => array:1 [ 0 => ""Windows"" ] "sec-ch-ua-mobile" => array:1 [ 0 => "?0" ] "sec-ch-ua" => array:1 [ 0 => ""Chromium";v="130", "HeadlessChrome";v="130", "Not?A_Brand";v="99"" ] "cache-control" => array:1 [ 0 => "no-cache" ] "pragma" => array:1 [ 0 => "no-cache" ] "sec-fetch-dest" => array:1 [ 0 => "document" ] "cf-ray" => array:1 [ 0 => "94da711eed5a70c4-ORD" ] "accept-encoding" => array:1 [ 0 => "gzip, br" ] "priority" => array:1 [ 0 => "u=0, i" ] "sec-fetch-user" => array:1 [ 0 => "?1" ] "sec-fetch-mode" => array:1 [ 0 => "navigate" ] "cf-visitor" => array:1 [ 0 => "{"scheme":"https"}" ] "host" => array:1 [ 0 => "www.corspedia.com" ] "content-length" => array:1 [ 0 => "" ] "content-type" => array:1 [ 0 => "" ] ]
        request_server
        0 of 0
        array:50 [ "USER" => "www-data" "HOME" => "/var/www" "HTTP_CF_IPCOUNTRY" => "US" "HTTP_CF_CONNECTING_IP" => "216.73.216.54" "HTTP_CDN_LOOP" => "cloudflare; loops=1" "HTTP_X_FORWARDED_PROTO" => "https" "HTTP_X_FORWARDED_FOR" => "216.73.216.54" "HTTP_SEC_FETCH_SITE" => "none" "HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" "HTTP_USER_AGENT" => "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)" "HTTP_UPGRADE_INSECURE_REQUESTS" => "1" "HTTP_SEC_CH_UA_PLATFORM" => ""Windows"" "HTTP_SEC_CH_UA_MOBILE" => "?0" "HTTP_SEC_CH_UA" => ""Chromium";v="130", "HeadlessChrome";v="130", "Not?A_Brand";v="99"" "HTTP_CACHE_CONTROL" => "no-cache" "HTTP_PRAGMA" => "no-cache" "HTTP_SEC_FETCH_DEST" => "document" "HTTP_CF_RAY" => "94da711eed5a70c4-ORD" "HTTP_ACCEPT_ENCODING" => "gzip, br" "HTTP_PRIORITY" => "u=0, i" "HTTP_SEC_FETCH_USER" => "?1" "HTTP_SEC_FETCH_MODE" => "navigate" "HTTP_CF_VISITOR" => "{"scheme":"https"}" "HTTP_HOST" => "www.corspedia.com" "REDIRECT_STATUS" => "200" "SERVER_NAME" => "corspedia.com" "SERVER_PORT" => "443" "SERVER_ADDR" => "141.95.147.152" "REMOTE_USER" => "" "REMOTE_PORT" => "19126" "REMOTE_ADDR" => "172.69.59.162" "SERVER_SOFTWARE" => "nginx/1.18.0" "GATEWAY_INTERFACE" => "CGI/1.1" "HTTPS" => "on" "REQUEST_SCHEME" => "https" "SERVER_PROTOCOL" => "HTTP/2.0" "DOCUMENT_ROOT" => "/var/www/corspedia/public" "DOCUMENT_URI" => "/index.php" "REQUEST_URI" => "/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/immutable-javascript-data-structures-with-immer" "SCRIPT_NAME" => "/index.php" "CONTENT_LENGTH" => "" "CONTENT_TYPE" => "" "REQUEST_METHOD" => "GET" "QUERY_STRING" => "" "SCRIPT_FILENAME" => "/var/www/corspedia/public/index.php" "PATH_INFO" => "" "FCGI_ROLE" => "RESPONDER" "PHP_SELF" => "/index.php" "REQUEST_TIME_FLOAT" => 1749575004.2654 "REQUEST_TIME" => 1749575004 ]
        request_cookies
        []
        
        response_headers
        0 of 0
        array:5 [ "content-type" => array:1 [ 0 => "text/html; charset=UTF-8" ] "cache-control" => array:1 [ 0 => "no-cache, private" ] "date" => array:1 [ 0 => "Tue, 10 Jun 2025 17:03:24 GMT" ] "set-cookie" => array:2 [ 0 => "XSRF-TOKEN=eyJpdiI6ImRaNi9IWXZma0hQK04wVFN3czFWc1E9PSIsInZhbHVlIjoiVDlRQjNyak5hRXl3cU1RczRnRmJXU1BleEwyUTBCelhweGU0RmpIMDJ0S2dZeU92V2lGa0kyN2Jab0xQYlMxejVESEo1Y3diZ3h2NjhTb3k5K3hLTmRXTGd6dlR4aGszTVdMcmVyTE9ZTDJ2bFFQYkVGSmh3UEh5Qll6OUN3YisiLCJtYWMiOiIzZWRkZjM1ZTYwZGUwMzExYzBlZGU5NzZjOGFhMmZhMGQwNWE5YzljM2FkN2E5Mzk3Y2E5MWZhNTVmZTViNzUxIiwidGFnIjoiIn0%3D; expires=Tue, 10 Jun 2025 19:03:25 GMT; Max-Age=7200; path=/; samesite=laxXSRF-TOKEN=eyJpdiI6ImRaNi9IWXZma0hQK04wVFN3czFWc1E9PSIsInZhbHVlIjoiVDlRQjNyak5hRXl3cU1RczRnRmJXU1BleEwyUTBCelhweGU0RmpIMDJ0S2dZeU92V2lGa0kyN2Jab0xQYlMxejVESEo1Y" 1 => "laravel_session=eyJpdiI6ImVNZ2I2S1pUczQyT2dtZ21jMHZaT1E9PSIsInZhbHVlIjoianBWSGNFSDR1NjVXazI0RjhXR3ZVMnRqdmVTMXRiWXlJR2lYVHB5UjhoQ3dXYVdYc0g4WHVTV2IvVkVERHExSEE0ZGQ1Z0h3TU9mMDlaWG9zRWtxSWU5c1JjQkVMQjdDakszN2F4MFRiYlo4UmZzenNuUmxVYW5VZnAzejlDaFUiLCJtYWMiOiI5M2JmNGZjMjUyYzUxNTcwMTNjMjQ1ZmJkNmVhYjFjNWIwZTYxYzY5MjVhYWI5OWI2MmJkNDlhZDk1NTc5MDI3IiwidGFnIjoiIn0%3D; expires=Tue, 10 Jun 2025 19:03:25 GMT; Max-Age=7200; path=/; httponly; samesite=laxlaravel_session=eyJpdiI6ImVNZ2I2S1pUczQyT2dtZ21jMHZaT1E9PSIsInZhbHVlIjoianBWSGNFSDR1NjVXazI0RjhXR3ZVMnRqdmVTMXRiWXlJR2lYVHB5UjhoQ3dXYVdYc0g4WHVTV2IvVkVERHExSEE0" ] "Set-Cookie" => array:2 [ 0 => "XSRF-TOKEN=eyJpdiI6ImRaNi9IWXZma0hQK04wVFN3czFWc1E9PSIsInZhbHVlIjoiVDlRQjNyak5hRXl3cU1RczRnRmJXU1BleEwyUTBCelhweGU0RmpIMDJ0S2dZeU92V2lGa0kyN2Jab0xQYlMxejVESEo1Y3diZ3h2NjhTb3k5K3hLTmRXTGd6dlR4aGszTVdMcmVyTE9ZTDJ2bFFQYkVGSmh3UEh5Qll6OUN3YisiLCJtYWMiOiIzZWRkZjM1ZTYwZGUwMzExYzBlZGU5NzZjOGFhMmZhMGQwNWE5YzljM2FkN2E5Mzk3Y2E5MWZhNTVmZTViNzUxIiwidGFnIjoiIn0%3D; expires=Tue, 10-Jun-2025 19:03:25 GMT; path=/XSRF-TOKEN=eyJpdiI6ImRaNi9IWXZma0hQK04wVFN3czFWc1E9PSIsInZhbHVlIjoiVDlRQjNyak5hRXl3cU1RczRnRmJXU1BleEwyUTBCelhweGU0RmpIMDJ0S2dZeU92V2lGa0kyN2Jab0xQYlMxejVESEo1Y" 1 => "laravel_session=eyJpdiI6ImVNZ2I2S1pUczQyT2dtZ21jMHZaT1E9PSIsInZhbHVlIjoianBWSGNFSDR1NjVXazI0RjhXR3ZVMnRqdmVTMXRiWXlJR2lYVHB5UjhoQ3dXYVdYc0g4WHVTV2IvVkVERHExSEE0ZGQ1Z0h3TU9mMDlaWG9zRWtxSWU5c1JjQkVMQjdDakszN2F4MFRiYlo4UmZzenNuUmxVYW5VZnAzejlDaFUiLCJtYWMiOiI5M2JmNGZjMjUyYzUxNTcwMTNjMjQ1ZmJkNmVhYjFjNWIwZTYxYzY5MjVhYWI5OWI2MmJkNDlhZDk1NTc5MDI3IiwidGFnIjoiIn0%3D; expires=Tue, 10-Jun-2025 19:03:25 GMT; path=/; httponlylaravel_session=eyJpdiI6ImVNZ2I2S1pUczQyT2dtZ21jMHZaT1E9PSIsInZhbHVlIjoianBWSGNFSDR1NjVXazI0RjhXR3ZVMnRqdmVTMXRiWXlJR2lYVHB5UjhoQ3dXYVdYc0g4WHVTV2IvVkVERHExSEE0" ] ]
        session_attributes
        0 of 0
        array:5 [ "_token" => "LbUICQj6kpwbV3MxhdjvrWCvgwwDYrbwWoJCfRyR" "locale" => "ar" "_previous" => array:1 [ "url" => "https://www.corspedia.com/ar/%D8%A7%D9%84%D8%AF%D9%88%D8%B1%D8%A7%D8%AA/immutable-javascript-data-structures-with-immer" ] "_flash" => array:2 [ "old" => [] "new" => [] ] "PHPDEBUGBAR_STACK_DATA" => [] ]