Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7c7f159

Browse files
committedJul 6, 2022
Replace legacy counter example with latest CRA+JS template
1 parent fd2ef49 commit 7c7f159

28 files changed

+18122
-33023
lines changed
 

‎examples/counter/.gitignore

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
1-
# See http://help.github.com/ignore-files/ for more about ignoring files.
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
22

33
# dependencies
4-
node_modules
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
510

611
# production
7-
build
12+
/build
813

914
# misc
1015
.DS_Store
11-
npm-debug.log
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*

‎examples/counter/README.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,46 @@
1-
# Redux Counter Example
1+
# Getting Started with Create React App and Redux
22

3-
This project template was built with [Create React App](https://github.com/facebookincubator/create-react-app), which provides a simple way to start React projects with no build configuration needed.
4-
5-
Projects built with Create-React-App include support for ES6 syntax, as well as several unofficial / not-yet-final forms of Javascript syntax such as Class Properties and JSX. See the list of [language features and polyfills supported by Create-React-App](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#supported-language-features-and-polyfills) for more information.
3+
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app), using the [Redux](https://redux.js.org/) and [Redux Toolkit](https://redux-toolkit.js.org/) template.
64

75
## Available Scripts
86

97
In the project directory, you can run:
108

119
### `npm start`
1210

13-
Runs the app in the development mode.<br>
14-
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11+
Runs the app in the development mode.\
12+
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13+
14+
The page will reload when you make changes.\
15+
You may also see any lint errors in the console.
1516

16-
The page will reload if you make edits.<br>
17-
You will also see any lint errors in the console.
17+
### `npm test`
18+
19+
Launches the test runner in the interactive watch mode.\
20+
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
1821

1922
### `npm run build`
2023

21-
Builds the app for production to the `build` folder.<br>
24+
Builds the app for production to the `build` folder.\
2225
It correctly bundles React in production mode and optimizes the build for the best performance.
2326

24-
The build is minified and the filenames include the hashes.<br>
27+
The build is minified and the filenames include the hashes.\
2528
Your app is ready to be deployed!
2629

30+
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31+
2732
### `npm run eject`
2833

29-
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
34+
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
35+
36+
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37+
38+
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39+
40+
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
3041

31-
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
42+
## Learn More
3243

33-
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
44+
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
3445

35-
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
46+
To learn React, check out the [React documentation](https://reactjs.org/).

‎examples/counter/package-lock.json

Lines changed: 17567 additions & 32809 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/counter/package.json

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
{
22
"name": "counter",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"private": true,
5-
"devDependencies": {
6-
"enzyme": "^3.11.0",
7-
"enzyme-adapter-react-16": "^1.15.2",
8-
"react-scripts": "^4.0.3"
9-
},
105
"dependencies": {
11-
"prop-types": "^15.7.2",
12-
"react": "^17.0.2",
13-
"react-dom": "^17.0.2",
14-
"react-redux": "^7.2.0",
15-
"redux": "^4.0.5"
6+
"@reduxjs/toolkit": "^1.8.3",
7+
"@testing-library/jest-dom": "^5.16.4",
8+
"@testing-library/react": "^13.3.0",
9+
"@testing-library/user-event": "^14.2.1",
10+
"react": "^18.2.0",
11+
"react-dom": "^18.2.0",
12+
"react-redux": "^8.0.2",
13+
"react-scripts": "5.0.1",
14+
"web-vitals": "^2.1.4"
1615
},
1716
"scripts": {
1817
"start": "react-scripts start",
1918
"build": "react-scripts build",
20-
"eject": "react-scripts eject",
21-
"test": "react-scripts test --env=node"
19+
"test": "react-scripts test",
20+
"eject": "react-scripts eject"
21+
},
22+
"eslintConfig": {
23+
"extends": [
24+
"react-app",
25+
"react-app/jest"
26+
]
2227
},
23-
"browserslist": [
24-
">0.2%",
25-
"not dead",
26-
"not ie <= 11",
27-
"not op_mini all"
28-
]
28+
"browserslist": {
29+
"production": [
30+
">0.2%",
31+
"not dead",
32+
"not op_mini all"
33+
],
34+
"development": [
35+
"last 1 chrome version",
36+
"last 1 firefox version",
37+
"last 1 safari version"
38+
]
39+
}
2940
}

‎examples/counter/public/favicon.ico

3.5 KB
Binary file not shown.

‎examples/counter/public/index.html

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
1-
<!doctype html>
1+
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="utf-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1">
6-
<title>Redux Counter Example</title>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
<meta name="theme-color" content="#000000" />
8+
<meta
9+
name="description"
10+
content="Web site created using create-react-app"
11+
/>
12+
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
13+
<!--
14+
manifest.json provides metadata used when your web app is installed on a
15+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
16+
-->
17+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18+
<!--
19+
Notice the use of %PUBLIC_URL% in the tags above.
20+
It will be replaced with the URL of the `public` folder during the build.
21+
Only files inside the `public` folder can be referenced from the HTML.
22+
23+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
24+
work correctly both with client-side routing and a non-root public URL.
25+
Learn how to configure a non-root public URL by running `npm run build`.
26+
-->
27+
<title>React Redux App</title>
728
</head>
829
<body>
30+
<noscript>You need to enable JavaScript to run this app.</noscript>
931
<div id="root"></div>
1032
<!--
1133
This HTML file is a template.
@@ -14,8 +36,8 @@
1436
You can add webfonts, meta tags, or analytics to this file.
1537
The build step will place the bundled scripts into the <body> tag.
1638
17-
To begin the development, run `npm start` in this folder.
18-
To create a production bundle, use `npm run build`.
39+
To begin the development, run `npm start` or `yarn start`.
40+
To create a production bundle, use `npm run build` or `yarn build`.
1941
-->
2042
</body>
2143
</html>

‎examples/counter/public/logo192.png

4.06 KB
Loading

‎examples/counter/public/logo512.png

11.8 KB
Loading

‎examples/counter/public/manifest.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"short_name": "React App",
3+
"name": "Create React App Sample",
4+
"icons": [
5+
{
6+
"src": "favicon.ico",
7+
"sizes": "64x64 32x32 24x24 16x16",
8+
"type": "image/x-icon"
9+
},
10+
{
11+
"src": "logo192.png",
12+
"type": "image/png",
13+
"sizes": "192x192"
14+
},
15+
{
16+
"src": "logo512.png",
17+
"type": "image/png",
18+
"sizes": "512x512"
19+
}
20+
],
21+
"start_url": ".",
22+
"display": "standalone",
23+
"theme_color": "#000000",
24+
"background_color": "#ffffff"
25+
}

‎examples/counter/public/robots.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# https://www.robotstxt.org/robotstxt.html
2+
User-agent: *

‎examples/counter/src/App.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.App {
2+
text-align: center;
3+
}
4+
5+
.App-logo {
6+
height: 40vmin;
7+
pointer-events: none;
8+
}
9+
10+
@media (prefers-reduced-motion: no-preference) {
11+
.App-logo {
12+
animation: App-logo-float infinite 3s ease-in-out;
13+
}
14+
}
15+
16+
.App-header {
17+
min-height: 100vh;
18+
display: flex;
19+
flex-direction: column;
20+
align-items: center;
21+
justify-content: center;
22+
font-size: calc(10px + 2vmin);
23+
}
24+
25+
.App-link {
26+
color: rgb(112, 76, 182);
27+
}
28+
29+
@keyframes App-logo-float {
30+
0% {
31+
transform: translateY(0);
32+
}
33+
50% {
34+
transform: translateY(10px);
35+
}
36+
100% {
37+
transform: translateY(0px);
38+
}
39+
}

‎examples/counter/src/App.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React from 'react';
2+
import logo from './logo.svg';
3+
import { Counter } from './features/counter/Counter';
4+
import './App.css';
5+
6+
function App() {
7+
return (
8+
<div className="App">
9+
<header className="App-header">
10+
<img src={logo} className="App-logo" alt="logo" />
11+
<Counter />
12+
<p>
13+
Edit <code>src/App.js</code> and save to reload.
14+
</p>
15+
<span>
16+
<span>Learn </span>
17+
<a
18+
className="App-link"
19+
href="https://reactjs.org/"
20+
target="_blank"
21+
rel="noopener noreferrer"
22+
>
23+
React
24+
</a>
25+
<span>, </span>
26+
<a
27+
className="App-link"
28+
href="https://redux.js.org/"
29+
target="_blank"
30+
rel="noopener noreferrer"
31+
>
32+
Redux
33+
</a>
34+
<span>, </span>
35+
<a
36+
className="App-link"
37+
href="https://redux-toolkit.js.org/"
38+
target="_blank"
39+
rel="noopener noreferrer"
40+
>
41+
Redux Toolkit
42+
</a>
43+
,<span> and </span>
44+
<a
45+
className="App-link"
46+
href="https://react-redux.js.org/"
47+
target="_blank"
48+
rel="noopener noreferrer"
49+
>
50+
React Redux
51+
</a>
52+
</span>
53+
</header>
54+
</div>
55+
);
56+
}
57+
58+
export default App;

‎examples/counter/src/App.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react';
3+
import { Provider } from 'react-redux';
4+
import { store } from './app/store';
5+
import App from './App';
6+
7+
test('renders learn react link', () => {
8+
const { getByText } = render(
9+
<Provider store={store}>
10+
<App />
11+
</Provider>
12+
);
13+
14+
expect(getByText(/learn/i)).toBeInTheDocument();
15+
});

‎examples/counter/src/app/store.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { configureStore } from '@reduxjs/toolkit';
2+
import counterReducer from '../features/counter/counterSlice';
3+
4+
export const store = configureStore({
5+
reducer: {
6+
counter: counterReducer,
7+
},
8+
});

‎examples/counter/src/components/Counter.js

Lines changed: 0 additions & 53 deletions
This file was deleted.

‎examples/counter/src/components/Counter.spec.js

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React, { useState } from 'react';
2+
import { useSelector, useDispatch } from 'react-redux';
3+
import {
4+
decrement,
5+
increment,
6+
incrementByAmount,
7+
incrementAsync,
8+
incrementIfOdd,
9+
selectCount,
10+
} from './counterSlice';
11+
import styles from './Counter.module.css';
12+
13+
export function Counter() {
14+
const count = useSelector(selectCount);
15+
const dispatch = useDispatch();
16+
const [incrementAmount, setIncrementAmount] = useState('2');
17+
18+
const incrementValue = Number(incrementAmount) || 0;
19+
20+
return (
21+
<div>
22+
<div className={styles.row}>
23+
<button
24+
className={styles.button}
25+
aria-label="Decrement value"
26+
onClick={() => dispatch(decrement())}
27+
>
28+
-
29+
</button>
30+
<span className={styles.value}>{count}</span>
31+
<button
32+
className={styles.button}
33+
aria-label="Increment value"
34+
onClick={() => dispatch(increment())}
35+
>
36+
+
37+
</button>
38+
</div>
39+
<div className={styles.row}>
40+
<input
41+
className={styles.textbox}
42+
aria-label="Set increment amount"
43+
value={incrementAmount}
44+
onChange={(e) => setIncrementAmount(e.target.value)}
45+
/>
46+
<button
47+
className={styles.button}
48+
onClick={() => dispatch(incrementByAmount(incrementValue))}
49+
>
50+
Add Amount
51+
</button>
52+
<button
53+
className={styles.asyncButton}
54+
onClick={() => dispatch(incrementAsync(incrementValue))}
55+
>
56+
Add Async
57+
</button>
58+
<button
59+
className={styles.button}
60+
onClick={() => dispatch(incrementIfOdd(incrementValue))}
61+
>
62+
Add If Odd
63+
</button>
64+
</div>
65+
</div>
66+
);
67+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
.row {
2+
display: flex;
3+
align-items: center;
4+
justify-content: center;
5+
}
6+
7+
.row > button {
8+
margin-left: 4px;
9+
margin-right: 8px;
10+
}
11+
.row:not(:last-child) {
12+
margin-bottom: 16px;
13+
}
14+
15+
.value {
16+
font-size: 78px;
17+
padding-left: 16px;
18+
padding-right: 16px;
19+
margin-top: 2px;
20+
font-family: 'Courier New', Courier, monospace;
21+
}
22+
23+
.button {
24+
appearance: none;
25+
background: none;
26+
font-size: 32px;
27+
padding-left: 12px;
28+
padding-right: 12px;
29+
outline: none;
30+
border: 2px solid transparent;
31+
color: rgb(112, 76, 182);
32+
padding-bottom: 4px;
33+
cursor: pointer;
34+
background-color: rgba(112, 76, 182, 0.1);
35+
border-radius: 2px;
36+
transition: all 0.15s;
37+
}
38+
39+
.textbox {
40+
font-size: 32px;
41+
padding: 2px;
42+
width: 64px;
43+
text-align: center;
44+
margin-right: 4px;
45+
}
46+
47+
.button:hover,
48+
.button:focus {
49+
border: 2px solid rgba(112, 76, 182, 0.4);
50+
}
51+
52+
.button:active {
53+
background-color: rgba(112, 76, 182, 0.2);
54+
}
55+
56+
.asyncButton {
57+
composes: button;
58+
position: relative;
59+
}
60+
61+
.asyncButton:after {
62+
content: '';
63+
background-color: rgba(112, 76, 182, 0.15);
64+
display: block;
65+
position: absolute;
66+
width: 100%;
67+
height: 100%;
68+
left: 0;
69+
top: 0;
70+
opacity: 0;
71+
transition: width 1s linear, opacity 0.5s ease 1s;
72+
}
73+
74+
.asyncButton:active:after {
75+
width: 0%;
76+
opacity: 1;
77+
transition: 0s;
78+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// A mock function to mimic making an async request for data
2+
export function fetchCount(amount = 1) {
3+
return new Promise((resolve) =>
4+
setTimeout(() => resolve({ data: amount }), 500)
5+
);
6+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
2+
import { fetchCount } from './counterAPI';
3+
4+
const initialState = {
5+
value: 0,
6+
status: 'idle',
7+
};
8+
9+
// The function below is called a thunk and allows us to perform async logic. It
10+
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
11+
// will call the thunk with the `dispatch` function as the first argument. Async
12+
// code can then be executed and other actions can be dispatched. Thunks are
13+
// typically used to make async requests.
14+
export const incrementAsync = createAsyncThunk(
15+
'counter/fetchCount',
16+
async (amount) => {
17+
const response = await fetchCount(amount);
18+
// The value we return becomes the `fulfilled` action payload
19+
return response.data;
20+
}
21+
);
22+
23+
export const counterSlice = createSlice({
24+
name: 'counter',
25+
initialState,
26+
// The `reducers` field lets us define reducers and generate associated actions
27+
reducers: {
28+
increment: (state) => {
29+
// Redux Toolkit allows us to write "mutating" logic in reducers. It
30+
// doesn't actually mutate the state because it uses the Immer library,
31+
// which detects changes to a "draft state" and produces a brand new
32+
// immutable state based off those changes
33+
state.value += 1;
34+
},
35+
decrement: (state) => {
36+
state.value -= 1;
37+
},
38+
// Use the PayloadAction type to declare the contents of `action.payload`
39+
incrementByAmount: (state, action) => {
40+
state.value += action.payload;
41+
},
42+
},
43+
// The `extraReducers` field lets the slice handle actions defined elsewhere,
44+
// including actions generated by createAsyncThunk or in other slices.
45+
extraReducers: (builder) => {
46+
builder
47+
.addCase(incrementAsync.pending, (state) => {
48+
state.status = 'loading';
49+
})
50+
.addCase(incrementAsync.fulfilled, (state, action) => {
51+
state.status = 'idle';
52+
state.value += action.payload;
53+
});
54+
},
55+
});
56+
57+
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
58+
59+
// The function below is called a selector and allows us to select a value from
60+
// the state. Selectors can also be defined inline where they're used instead of
61+
// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`
62+
export const selectCount = (state) => state.counter.value;
63+
64+
// We can also write thunks by hand, which may contain both sync and async logic.
65+
// Here's an example of conditionally dispatching actions based on current state.
66+
export const incrementIfOdd = (amount) => (dispatch, getState) => {
67+
const currentValue = selectCount(getState());
68+
if (currentValue % 2 === 1) {
69+
dispatch(incrementByAmount(amount));
70+
}
71+
};
72+
73+
export default counterSlice.reducer;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import counterReducer, {
2+
increment,
3+
decrement,
4+
incrementByAmount,
5+
} from './counterSlice';
6+
7+
describe('counter reducer', () => {
8+
const initialState = {
9+
value: 3,
10+
status: 'idle',
11+
};
12+
it('should handle initial state', () => {
13+
expect(counterReducer(undefined, { type: 'unknown' })).toEqual({
14+
value: 0,
15+
status: 'idle',
16+
});
17+
});
18+
19+
it('should handle increment', () => {
20+
const actual = counterReducer(initialState, increment());
21+
expect(actual.value).toEqual(4);
22+
});
23+
24+
it('should handle decrement', () => {
25+
const actual = counterReducer(initialState, decrement());
26+
expect(actual.value).toEqual(2);
27+
});
28+
29+
it('should handle incrementByAmount', () => {
30+
const actual = counterReducer(initialState, incrementByAmount(2));
31+
expect(actual.value).toEqual(5);
32+
});
33+
});

‎examples/counter/src/index.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
body {
2+
margin: 0;
3+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5+
sans-serif;
6+
-webkit-font-smoothing: antialiased;
7+
-moz-osx-font-smoothing: grayscale;
8+
}
9+
10+
code {
11+
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12+
monospace;
13+
}

‎examples/counter/src/index.js

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
import React from 'react'
2-
import ReactDOM from 'react-dom'
3-
import { createStore } from 'redux'
4-
import Counter from './components/Counter'
5-
import counter from './reducers'
1+
import React from 'react';
2+
import { createRoot } from 'react-dom/client';
3+
import { Provider } from 'react-redux';
4+
import { store } from './app/store';
5+
import App from './App';
6+
import reportWebVitals from './reportWebVitals';
7+
import './index.css';
68

7-
const store = createStore(counter)
8-
const rootEl = document.getElementById('root')
9+
const container = document.getElementById('root');
10+
const root = createRoot(container);
911

10-
const render = () => ReactDOM.render(
11-
<Counter
12-
value={store.getState()}
13-
onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
14-
onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
15-
/>,
16-
rootEl
17-
)
12+
root.render(
13+
<React.StrictMode>
14+
<Provider store={store}>
15+
<App />
16+
</Provider>
17+
</React.StrictMode>
18+
);
1819

19-
render()
20-
store.subscribe(render)
20+
// If you want to start measuring performance in your app, pass a function
21+
// to log results (for example: reportWebVitals(console.log))
22+
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
23+
reportWebVitals();

‎examples/counter/src/logo.svg

Lines changed: 1 addition & 0 deletions
Loading

‎examples/counter/src/reducers/index.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎examples/counter/src/reducers/index.spec.js

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const reportWebVitals = onPerfEntry => {
2+
if (onPerfEntry && onPerfEntry instanceof Function) {
3+
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4+
getCLS(onPerfEntry);
5+
getFID(onPerfEntry);
6+
getFCP(onPerfEntry);
7+
getLCP(onPerfEntry);
8+
getTTFB(onPerfEntry);
9+
});
10+
}
11+
};
12+
13+
export default reportWebVitals;

‎examples/counter/src/setupTests.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { configure } from 'enzyme'
2-
import Adapter from 'enzyme-adapter-react-16'
3-
4-
configure({ adapter: new Adapter() })
1+
// jest-dom adds custom jest matchers for asserting on DOM nodes.
2+
// allows you to do things like:
3+
// expect(element).toHaveTextContent(/react/i)
4+
// learn more: https://github.com/testing-library/jest-dom
5+
import '@testing-library/jest-dom/extend-expect';

0 commit comments

Comments
 (0)
Please sign in to comment.