Repository: reduxjs/redux-toolkit
Pull request #615 (2020-06-17 02:48:55)

Add styling for blockquotes on darkmode
- Addresses #614 

Full disclosure: I'm not a designer 😅 

**Updated Preview:**

![image](https://user-images.githubusercontent.com/784953/84919594-fd44de80-b076-11ea-88bc-650eff7a7508.png)



netlify[bot]: Deploy preview for *redux-starter-kit-docs* ready!

Built with commit 7399a8fcb2ffb5b7cf2a0224e5d0f4ee4302b3f7

https://deploy-preview-615--redux-starter-kit-docs.netlify.app
codesandbox[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/reduxjs/redux-toolkit/pr/615/builds/32935) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 7399a8fcb2ffb5b7cf2a0224e5d0f4ee4302b3f7:

|Sandbox| Source |
|--|--|
|[optimistic-moore-qgyjl](https://codesandbox.io/s/optimistic-moore-qgyjl)| Configuration |
|[practical-agnesi-6pkhp](https://codesandbox.io/s/practical-agnesi-6pkhp)| Configuration |
|[nostalgic-sinoussi-osqcm](https://codesandbox.io/s/nostalgic-sinoussi-osqcm)| Configuration |

msutkowski: Or another option of just setting `color: #000;` on blockquote:

![image](https://user-images.githubusercontent.com/784953/84850212-08aef000-b00c-11ea-92d3-979da9d844f3.png)


Patch:
diff --git a/docs/api/createAsyncThunk.md b/docs/api/createAsyncThunk.md
index 08a8202f..c5b00bae 100644
--- a/docs/api/createAsyncThunk.md
+++ b/docs/api/createAsyncThunk.md
@@ -195,7 +195,7 @@ const reducer1 = createReducer(initialState, {
   [fetchUserById.fulfilled]: (state, action) => {}
 })
 
-const reducer2 = createReducer(initialState, build => {
+const reducer2 = createReducer(initialState, builder => {
   builder.addCase(fetchUserById.fulfilled, (state, action) => {})
 })
 
diff --git a/docs/usage/usage-guide.md b/docs/usage/usage-guide.md
index 86ce1d83..15a76ad4 100644
--- a/docs/usage/usage-guide.md
+++ b/docs/usage/usage-guide.md
@@ -1021,3 +1021,18 @@ export const usersAdapter = createEntityAdapter({
   sortComparer: (a, b) => a.first_name.localeCompare(b.first_name)
 })
 ```
+
+## Working with Non-serializable Data
+
+Occasionally, you may have actions that need to accept non-serializable data. This should be done very rarely and only if necessary. These non-serializable payloads shouldn't ever make it into your application state through a reducer. However, if you're using libraries such as redux saga or you're using middleware that could reasonably use non-serializable data you'll want to do the following:
+
+```js
+configureStore({
+  //...
+  middleware: getDefaultMiddleware({
+    serializableCheck: {
+      ignoredActions: ['your/action']
+    }
+  })
+})
+```
diff --git a/src/entities/fixtures/book.ts b/src/entities/fixtures/book.ts
index 6191374a..8c0a8d5d 100644
--- a/src/entities/fixtures/book.ts
+++ b/src/entities/fixtures/book.ts
@@ -1,6 +1,7 @@
 export interface BookModel {
   id: string
   title: string
+  author?: string
 }
 
 export const AClockworkOrange: BookModel = Object.freeze({
@@ -17,3 +18,9 @@ export const TheGreatGatsby: BookModel = Object.freeze({
   id: 'tgg',
   title: 'The Great Gatsby'
 })
+
+export const TheHobbit: BookModel = Object.freeze({
+  id: 'th',
+  title: 'The Hobbit',
+  author: 'J. R. R. Tolkien'
+})
diff --git a/src/entities/unsorted_state_adapter.ts b/src/entities/unsorted_state_adapter.ts
index 13f20733..4fec5c1f 100644
--- a/src/entities/unsorted_state_adapter.ts
+++ b/src/entities/unsorted_state_adapter.ts
@@ -16,7 +16,7 @@ export function createUnsortedStateAdapter<T>(
 ): EntityStateAdapter<T> {
   type R = EntityState<T>
 
-  function addOneMutably(entity: T, state: EntityState<T>): void {
+  function addOneMutably(entity: T, state: R): void {
     const key = selectIdValue(entity, selectId)
 
     if (key in state.entities) {
@@ -108,10 +108,15 @@ export function createUnsortedStateAdapter<T>(
       if (update.id in state.entities) {
         // If there are multiple updates to one entity, merge them together
         updatesPerEntity[update.id] = {
+          id: update.id,
           // Spreads ignore falsy values, so this works even if there isn't
           // an existing update already at this key
-          ...updatesPerEntity[update.id],
-          ...update
+          changes: {
+            ...(updatesPerEntity[update.id]
+              ? updatesPerEntity[update.id].changes
+              : null),
+            ...update.changes
+          }
         }
       }
     })
diff --git a/src/serializableStateInvariantMiddleware.ts b/src/serializableStateInvariantMiddleware.ts
index a69aaad2..03bda311 100644
--- a/src/serializableStateInvariantMiddleware.ts
+++ b/src/serializableStateInvariantMiddleware.ts
@@ -176,7 +176,8 @@ export function createSerializableStateInvariantMiddleware(
           value,
           '\nTake a look at the logic that dispatched this action: ',
           action,
-          '\n(See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)'
+          '\n(See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)',
+          '\n(To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)'
         )
       }
     })
diff --git a/website/src/css/custom.css b/website/src/css/custom.css
index 82258b8f..a712b6c5 100644
--- a/website/src/css/custom.css
+++ b/website/src/css/custom.css
@@ -62,6 +62,11 @@ blockquote {
   border-radius: var(--ifm-global-radius);
 }
 
+html[data-theme='dark'] blockquote {
+   border-left-color: var(--ifm-color-primary);
+   color: #000;
+}
+
 .docusaurus-highlight-code-line {
   background-color: rgb(72, 77, 91);
   display: block;


Test patch:
diff --git a/src/entities/unsorted_state_adapter.test.ts b/src/entities/unsorted_state_adapter.test.ts
index 44f5d696..3e4521b5 100644
--- a/src/entities/unsorted_state_adapter.test.ts
+++ b/src/entities/unsorted_state_adapter.test.ts
@@ -4,7 +4,8 @@ import {
   BookModel,
   TheGreatGatsby,
   AClockworkOrange,
-  AnimalFarm
+  AnimalFarm,
+  TheHobbit
 } from './fixtures/book'
 import { createNextState } from '..'
 
@@ -466,12 +467,20 @@ describe('Unsorted State Adapter', () => {
     test('updateMany', () => {
       const firstChange = { title: 'First Change' }
       const secondChange = { title: 'Second Change' }
-      const withMany = adapter.setAll(state, [TheGreatGatsby, AClockworkOrange])
+      const thirdChange = { title: 'Third Change' }
+      const fourthChange = { author: 'Fourth Change' }
+      const withMany = adapter.setAll(state, [
+        TheGreatGatsby,
+        AClockworkOrange,
+        TheHobbit
+      ])
 
       const result = createNextState(withMany, draft => {
         adapter.updateMany(draft, [
-          { id: TheGreatGatsby.id, changes: firstChange },
-          { id: AClockworkOrange.id, changes: secondChange }
+          { id: TheHobbit.id, changes: firstChange },
+          { id: TheGreatGatsby.id, changes: secondChange },
+          { id: AClockworkOrange.id, changes: thirdChange },
+          { id: TheHobbit.id, changes: fourthChange }
         ])
       })
 
@@ -480,16 +489,22 @@ describe('Unsorted State Adapter', () => {
           "entities": Object {
             "aco": Object {
               "id": "aco",
-              "title": "Second Change",
+              "title": "Third Change",
             },
             "tgg": Object {
               "id": "tgg",
+              "title": "Second Change",
+            },
+            "th": Object {
+              "author": "Fourth Change",
+              "id": "th",
               "title": "First Change",
             },
           },
           "ids": Array [
             "tgg",
             "aco",
+            "th",
           ],
         }
       `)
diff --git a/src/serializableStateInvariantMiddleware.test.ts b/src/serializableStateInvariantMiddleware.test.ts
index a512ed50..6e769776 100644
--- a/src/serializableStateInvariantMiddleware.test.ts
+++ b/src/serializableStateInvariantMiddleware.test.ts
@@ -111,7 +111,8 @@ describe('serializableStateInvariantMiddleware', () => {
       Take a look at the logic that dispatched this action:  Object {
         \\"type\\": Symbol(SOME_CONSTANT),
       } 
-      (See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)"
+      (See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants) 
+      (To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)"
     `)
   })
 
@@ -363,7 +364,8 @@ describe('serializableStateInvariantMiddleware', () => {
           },
           \\"type\\": \\"test\\",
         } 
-        (See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)"
+        (See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants) 
+        (To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)"
       `)
     })