Skip to content
This repository has been archived by the owner on Apr 30, 2023. It is now read-only.

Commit

Permalink
Merge pull request #36 from reduxjs/feature/port-ts-changes
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson authored Apr 5, 2021
2 parents 19d2005 + 4de628f commit dadb45a
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 98 deletions.
40 changes: 11 additions & 29 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "cra-template-redux",
"version": "1.0.2",
"scripts": {
"prettify": "prettier --write './template/src/**/*.js'",
"format": "prettier --write ./template/src/**/*.js",
"lint": "eslint './template/src/**/*.js'",
"test": "jest"
},
Expand Down Expand Up @@ -34,7 +34,7 @@
"devDependencies": {
"@babel/preset-env": "^7.7.6",
"@babel/preset-react": "^7.7.4",
"@reduxjs/toolkit": "^1.1.0",
"@reduxjs/toolkit": "^1.5.1",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"babel-eslint": "^10.0.3",
Expand All @@ -48,7 +48,7 @@
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^2.3.0",
"jest": "^24.9.0",
"prettier": "^1.19.1",
"prettier": "^2.2.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3",
Expand Down
6 changes: 3 additions & 3 deletions template.json
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"
}
}
}
}
24 changes: 0 additions & 24 deletions template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,3 @@ You don’t have to ever use `eject`. The curated feature set is suitable for sm
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

### Code Splitting

This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting

### Analyzing the Bundle Size

This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size

### Making a Progressive Web App

This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app

### Advanced Configuration

This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration

### Deployment

This section has moved here: https://facebook.github.io/create-react-app/docs/deployment

### `npm run build` fails to minify

This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
4 changes: 2 additions & 2 deletions template/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
transform: translateY(0);
}
50% {
transform: translateY(10px)
transform: translateY(10px);
}
100% {
transform: translateY(0px)
transform: translateY(0px);
}
}
2 changes: 1 addition & 1 deletion template/src/App.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';
import store from './app/store';
import { store } from './app/store';
import App from './App';

test('renders learn react link', () => {
Expand Down
2 changes: 1 addition & 1 deletion template/src/app/store.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';

export default configureStore({
export const store = configureStore({
reducer: {
counter: counterReducer,
},
Expand Down
17 changes: 12 additions & 5 deletions template/src/features/counter/Counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
increment,
incrementByAmount,
incrementAsync,
incrementIfOdd,
selectCount,
} from './counterSlice';
import styles from './Counter.module.css';
Expand All @@ -14,6 +15,8 @@ export function Counter() {
const dispatch = useDispatch();
const [incrementAmount, setIncrementAmount] = useState('2');

const incrementValue = Number(incrementAmount) || 0;

return (
<div>
<div className={styles.row}>
Expand All @@ -38,22 +41,26 @@ export function Counter() {
className={styles.textbox}
aria-label="Set increment amount"
value={incrementAmount}
onChange={e => setIncrementAmount(e.target.value)}
onChange={(e) => setIncrementAmount(e.target.value)}
/>
<button
className={styles.button}
onClick={() =>
dispatch(incrementByAmount(Number(incrementAmount) || 0))
}
onClick={() => dispatch(incrementByAmount(incrementValue))}
>
Add Amount
</button>
<button
className={styles.asyncButton}
onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))}
onClick={() => dispatch(incrementAsync(incrementValue))}
>
Add Async
</button>
<button
className={styles.button}
onClick={() => dispatch(incrementIfOdd(incrementValue))}
>
Add If Odd
</button>
</div>
</div>
);
Expand Down
14 changes: 9 additions & 5 deletions template/src/features/counter/Counter.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
justify-content: center;
}

.row > button {
margin-left: 4px;
margin-right: 8px;
}
.row:not(:last-child) {
margin-bottom: 16px;
}
Expand Down Expand Up @@ -37,10 +41,11 @@
padding: 2px;
width: 64px;
text-align: center;
margin-right: 8px;
margin-right: 4px;
}

.button:hover, .button:focus {
.button:hover,
.button:focus {
border: 2px solid rgba(112, 76, 182, 0.4);
}

Expand All @@ -51,11 +56,10 @@
.asyncButton {
composes: button;
position: relative;
margin-left: 8px;
}

.asyncButton:after {
content: "";
content: '';
background-color: rgba(112, 76, 182, 0.15);
display: block;
position: absolute;
Expand All @@ -70,5 +74,5 @@
.asyncButton:active:after {
width: 0%;
opacity: 1;
transition: 0s
transition: 0s;
}
6 changes: 6 additions & 0 deletions template/src/features/counter/counterAPI.js
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)
);
}
69 changes: 50 additions & 19 deletions template/src/features/counter/counterSlice.js
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;
Loading

0 comments on commit dadb45a

Please sign in to comment.