This repository has been archived by the owner on Apr 30, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 232
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from reduxjs/feature/port-ts-changes
- Loading branch information
Showing
14 changed files
with
137 additions
and
98 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
{ | ||
"package": { | ||
"dependencies": { | ||
"@reduxjs/toolkit": "^1.1.0", | ||
"@reduxjs/toolkit": "^1.5.1", | ||
"@testing-library/jest-dom": "^4.2.4", | ||
"@testing-library/react": "^9.3.2", | ||
"@testing-library/user-event": "^7.1.2", | ||
"react-redux": "^7.1.3" | ||
"react-redux": "^7.2.3" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// A mock function to mimic making an async request for data | ||
export function fetchCount(amount = 1) { | ||
return new Promise((resolve) => | ||
setTimeout(() => resolve({ data: amount }), 500) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,73 @@ | ||
import { createSlice } from '@reduxjs/toolkit'; | ||
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; | ||
import { fetchCount } from './counterAPI'; | ||
|
||
const initialState = { | ||
value: 0, | ||
status: 'idle', | ||
}; | ||
|
||
// The function below is called a thunk and allows us to perform async logic. It | ||
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This | ||
// will call the thunk with the `dispatch` function as the first argument. Async | ||
// code can then be executed and other actions can be dispatched. Thunks are | ||
// typically used to make async requests. | ||
export const incrementAsync = createAsyncThunk( | ||
'counter/fetchCount', | ||
async (amount) => { | ||
const response = await fetchCount(amount); | ||
// The value we return becomes the `fulfilled` action payload | ||
return response.data; | ||
} | ||
); | ||
|
||
export const counterSlice = createSlice({ | ||
name: 'counter', | ||
initialState: { | ||
value: 0, | ||
}, | ||
initialState, | ||
// The `reducers` field lets us define reducers and generate associated actions | ||
reducers: { | ||
increment: state => { | ||
increment: (state) => { | ||
// Redux Toolkit allows us to write "mutating" logic in reducers. It | ||
// doesn't actually mutate the state because it uses the Immer library, | ||
// which detects changes to a "draft state" and produces a brand new | ||
// immutable state based on those changes | ||
// immutable state based off those changes | ||
state.value += 1; | ||
}, | ||
decrement: state => { | ||
decrement: (state) => { | ||
state.value -= 1; | ||
}, | ||
// Use the PayloadAction type to declare the contents of `action.payload` | ||
incrementByAmount: (state, action) => { | ||
state.value += action.payload; | ||
}, | ||
}, | ||
// The `extraReducers` field lets the slice handle actions defined elsewhere, | ||
// including actions generated by createAsyncThunk or in other slices. | ||
extraReducers: (builder) => { | ||
builder | ||
.addCase(incrementAsync.pending, (state) => { | ||
state.status = 'loading'; | ||
}) | ||
.addCase(incrementAsync.fulfilled, (state, action) => { | ||
state.status = 'idle'; | ||
state.value += action.payload; | ||
}); | ||
}, | ||
}); | ||
|
||
export const { increment, decrement, incrementByAmount } = counterSlice.actions; | ||
|
||
// The function below is called a thunk and allows us to perform async logic. It | ||
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This | ||
// will call the thunk with the `dispatch` function as the first argument. Async | ||
// code can then be executed and other actions can be dispatched | ||
export const incrementAsync = amount => dispatch => { | ||
setTimeout(() => { | ||
dispatch(incrementByAmount(amount)); | ||
}, 1000); | ||
}; | ||
|
||
// The function below is called a selector and allows us to select a value from | ||
// the state. Selectors can also be defined inline where they're used instead of | ||
// in the slice file. For example: `useSelector((state) => state.counter.value)` | ||
export const selectCount = state => state.counter.value; | ||
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)` | ||
export const selectCount = (state) => state.counter.value; | ||
|
||
// We can also write thunks by hand, which may contain both sync and async logic. | ||
// Here's an example of conditionally dispatching actions based on current state. | ||
export const incrementIfOdd = (amount) => (dispatch, getState) => { | ||
const currentValue = selectCount(getState()); | ||
if (currentValue % 2 === 1) { | ||
dispatch(incrementByAmount(amount)); | ||
} | ||
}; | ||
|
||
export default counterSlice.reducer; |
Oops, something went wrong.