Skip to content

Commit 1dfdc27

Browse files
committed
feat: react-hooks-event
1 parent e705838 commit 1dfdc27

13 files changed

+259
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
<td><a href="./packages/react-context-reducer">packages/react-context-reducer</a></td>
5858
</tr>
5959

60+
<tr>
61+
<td><a href="https://juejin.cn/post/7265515986471501839">Hooks与事件绑定</a></td>
62+
<td><a href="./packages/react-hooks-event">packages/react-hooks-event</a></td>
63+
</tr>
64+
6065
<tr>
6166
<td><a href="https://juejin.cn/post/7276990690546270247">ReactPortals传送门</a></td>
6267
<td><a href="./packages/react-portals">packages/react-portals</a></td>

packages/react-hooks-event/.env

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
BROWSER=none
2+
PUBLIC_URL=.
3+
DISABLE_ESLINT_PLUGIN=true
4+
GENERATE_SOURCEMAP=false
5+
TSC_COMPILE_ON_ERROR=true
6+
TSC_WATCHFILE=UseFsEventsWithFallbackDynamicPolling
7+
SKIP_PREFLIGHT_CHECK=true
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "react-hooks-event",
3+
"version": "1.0.0",
4+
"description": "",
5+
"keywords": [],
6+
"main": "src/index.tsx",
7+
"dependencies": {
8+
"react": "17.0.2",
9+
"react-dom": "17.0.2",
10+
"react-scripts": "4.0.3"
11+
},
12+
"devDependencies": {
13+
"@types/react": "17.0.20",
14+
"@types/react-dom": "17.0.9"
15+
},
16+
"scripts": {
17+
"dev": "react-scripts start",
18+
"build": "react-scripts build",
19+
"test": "react-scripts test --env=jsdom",
20+
"eject": "react-scripts eject"
21+
},
22+
"browserslist": [
23+
">0.2%",
24+
"not dead",
25+
"not ie <= 11",
26+
"not op_mini all"
27+
]
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7+
<meta name="theme-color" content="#000000">
8+
<!--
9+
manifest.json provides metadata used when your web app is added to the
10+
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
11+
-->
12+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
13+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
14+
<!--
15+
Notice the use of %PUBLIC_URL% in the tags above.
16+
It will be replaced with the URL of the `public` folder during the build.
17+
Only files inside the `public` folder can be referenced from the HTML.
18+
19+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
20+
work correctly both with client-side routing and a non-root public URL.
21+
Learn how to configure a non-root public URL by running `npm run build`.
22+
-->
23+
<title>React App</title>
24+
</head>
25+
26+
<body>
27+
<noscript>
28+
You need to enable JavaScript to run this app.
29+
</noscript>
30+
<div id="root"></div>
31+
<!--
32+
This HTML file is a template.
33+
If you open it directly in the browser, you will see an empty page.
34+
35+
You can add webfonts, meta tags, or analytics to this file.
36+
The build step will place the bundled scripts into the <body> tag.
37+
38+
To begin the development, run `npm start` or `yarn start`.
39+
To create a production bundle, use `npm run build` or `yarn build`.
40+
-->
41+
</body>
42+
43+
</html>
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { CounterNormal } from "./counter-normal";
2+
import { CounterNative } from "./counter-native";
3+
import { CounterCallback } from "./counter-callback";
4+
import "./styles.css";
5+
6+
interface Props {}
7+
8+
const App: React.FC<Props> = (props) => {
9+
return (
10+
<div>
11+
<div>Hooks事件绑定</div>
12+
<CounterNormal />
13+
<div>原生事件绑定</div>
14+
<CounterNative />
15+
<div>useCallback</div>
16+
<CounterCallback />
17+
</div>
18+
);
19+
};
20+
21+
export default App;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useCallback, useEffect, useRef, useState } from "react";
2+
3+
export const CounterCallback: React.FC = () => {
4+
const ref1 = useRef<HTMLButtonElement>(null);
5+
const ref2 = useRef<HTMLButtonElement>(null);
6+
const [count, setCount] = useState(0);
7+
8+
const add = () => {
9+
setCount(count + 1);
10+
};
11+
12+
const logCount1 = () => console.log(count);
13+
14+
useEffect(() => {
15+
const el = ref1.current;
16+
el?.addEventListener("click", logCount1);
17+
return () => {
18+
el?.removeEventListener("click", logCount1);
19+
};
20+
}, []);
21+
22+
const logCount2 = useCallback(() => {
23+
console.log(count);
24+
}, [count]);
25+
26+
useEffect(() => {
27+
const el = ref2.current;
28+
el?.addEventListener("click", logCount2);
29+
return () => {
30+
el?.removeEventListener("click", logCount2);
31+
};
32+
}, [logCount2]);
33+
34+
return (
35+
<div>
36+
{count}
37+
<div>
38+
<button onClick={add}>count++</button>
39+
<button ref={ref1}>log count 1</button>
40+
<button ref={ref2}>log count 2</button>
41+
</div>
42+
</div>
43+
);
44+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { useEffect, useRef, useState } from "react";
2+
3+
export const CounterNative: React.FC = () => {
4+
const ref1 = useRef<HTMLButtonElement>(null);
5+
const ref2 = useRef<HTMLButtonElement>(null);
6+
const [count, setCount] = useState(0);
7+
8+
const add = () => {
9+
setCount(count + 1);
10+
};
11+
12+
useEffect(() => {
13+
const el = ref1.current;
14+
const handler = () => console.log(count);
15+
el?.addEventListener("click", handler);
16+
return () => {
17+
el?.removeEventListener("click", handler);
18+
};
19+
}, []);
20+
21+
useEffect(() => {
22+
const el = ref2.current;
23+
const handler = () => console.log(count);
24+
el?.addEventListener("click", handler);
25+
return () => {
26+
el?.removeEventListener("click", handler);
27+
};
28+
}, [count]);
29+
30+
return (
31+
<div>
32+
{count}
33+
<div>
34+
<button onClick={add}>count++</button>
35+
<button ref={ref1}>log count 1</button>
36+
<button ref={ref2}>log count 2</button>
37+
</div>
38+
</div>
39+
);
40+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { useState } from "react";
2+
3+
export const CounterNormal: React.FC = () => {
4+
const [count, setCount] = useState(0);
5+
const add = () => {
6+
setCount(count + 1);
7+
};
8+
return (
9+
<div>
10+
{count}
11+
<div>
12+
<button onClick={add}>count++</button>
13+
</div>
14+
</div>
15+
);
16+
};
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { render } from "react-dom";
2+
3+
import App from "./App";
4+
5+
const rootElement = document.getElementById("root");
6+
render(<App />, rootElement);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="react-scripts" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.App {
2+
font-family: sans-serif;
3+
text-align: center;
4+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"include": [
3+
"./src/**/*"
4+
],
5+
"compilerOptions": {
6+
"strict": true,
7+
"esModuleInterop": true,
8+
"lib": [
9+
"dom",
10+
"es2015"
11+
],
12+
"jsx": "react-jsx",
13+
"target": "es5",
14+
"allowJs": true,
15+
"skipLibCheck": true,
16+
"allowSyntheticDefaultImports": true,
17+
"forceConsistentCasingInFileNames": true,
18+
"noFallthroughCasesInSwitch": true,
19+
"module": "esnext",
20+
"moduleResolution": "node",
21+
"resolveJsonModule": true,
22+
"isolatedModules": true,
23+
"noEmit": true
24+
}
25+
}

pnpm-lock.yaml

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)