Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a768677

Browse files
author
victorsun
committed
upd: react
1 parent 34f9200 commit a768677

File tree

7 files changed

+194
-0
lines changed

7 files changed

+194
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
3+
const A = (props) => {
4+
console.log('A渲染');
5+
6+
return (
7+
<div>
8+
<h2>组件A</h2>
9+
<button onClick={props.onAdd}>App.onAdd</button>
10+
</div>
11+
);
12+
};
13+
14+
export default React.memo(A);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React, {useCallback, useState} from 'react';
2+
import A from "./A";
3+
4+
const App = () => {
5+
const [count, setCount] = useState(1);
6+
const [num] = useState(1);
7+
8+
// useCallback 钩子函数,用于缓存回调函数
9+
// 若不使用 useCallback,A 组件 onAdd 属性传入的 clickHandler 会变,导致 memo 失效
10+
// 若不指定依赖数组,每次都会重建,注意一定要将回调函数中用到的所有变量都设置到依赖数组中
11+
12+
const clickHandler = useCallback(() => {
13+
setCount(prevState => prevState + num);
14+
}, [num]);
15+
16+
return (
17+
<div>
18+
<h2>App - {count}</h2>
19+
<button onClick={clickHandler}>App</button>
20+
<A onAdd={clickHandler} />
21+
</div>
22+
);
23+
};
24+
25+
export default App;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import ReactDOM from 'react-dom/client';
2+
import App from "../test/src/App";
3+
4+
const root = ReactDOM.createRoot(document.getElementById('root'));
5+
root.render(<App/>);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React, {useEffect} from 'react';
2+
import useFetch from "./hooks/useFetch";
3+
4+
const App = () => {
5+
6+
const { data: stuData, loading, error, fetchData } = useFetch();
7+
8+
// 初始化fetch
9+
useEffect(() => {
10+
fetchData();
11+
}, []);
12+
13+
const loadDataHandler = () => {
14+
fetchData();
15+
};
16+
17+
return (
18+
<div className="app">
19+
<button onClick={loadDataHandler}>加载数据</button>
20+
{/* {(!loading && !error) && <StudentList stus={stuData}/>} */}
21+
{loading && <p>数据正在加载中...</p>}
22+
{error && <p>数据加载异常!</p>}
23+
</div>
24+
);
25+
};
26+
27+
export default App;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* React中的钩子函数只能在函数组件或自定钩子中调用
3+
* 自定义钩子其实是一个名字为use开头的普通函数,可以将React中钩子函数提取到一个公共区域
4+
*/
5+
import {useCallback, useState} from "react";
6+
7+
export default function useFetch(reqObj, cb) {
8+
const [data, setData] = useState([]);
9+
const [loading, setLoading] = useState(false);
10+
const [error, setError] = useState(null);
11+
12+
const fetchData = useCallback(async (body) => {
13+
try {
14+
setLoading(true);
15+
setError(null);
16+
const res = await fetch('http://localhost:8080/api/'+reqObj.url, {
17+
method:reqObj.method || 'get',
18+
headers:{
19+
"Content-type":"application/json"
20+
},
21+
body:body?JSON.stringify({data:body}):null,
22+
23+
});
24+
if (res.ok) {
25+
const data = await res.json();
26+
setData(data.data);
27+
cb && cb();
28+
} else {
29+
throw new Error('数据加载失败!');
30+
}
31+
} catch (e) {
32+
console.log(e);
33+
setError(e);
34+
} finally {
35+
setLoading(false);
36+
}
37+
}, []);
38+
39+
// 设置返回
40+
return {
41+
loading,
42+
error,
43+
data,
44+
fetchData
45+
};
46+
}
47+
48+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import ReactDOM from "react-dom/client";
2+
import App from "./App";
3+
4+
const root = ReactDOM.createRoot(document.getElementById('root'));
5+
root.render(<App/>);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<!DOCTYPE html>
2+
<html lang="zh">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Redux</title>
6+
</head>
7+
<body>
8+
9+
<div>
10+
<button id="sub">减少</button>
11+
<span id="ageSpan">1</span>
12+
<button id="add">增加</button>
13+
<button id="addFive">加5</button>
14+
</div>
15+
16+
<script src="https://unpkg.com/redux@4.2.0/dist/redux.js"></script>
17+
18+
<script>
19+
/**
20+
* 1. 创建reducer整合函数
21+
* 2. 通过reducer对象创建store
22+
* 3. 对store中的state进行订阅
23+
* 4. 通过dispatch派发state的操作指令
24+
*/
25+
26+
const subBtn = document.getElementById('sub');
27+
const addBtn = document.getElementById('add');
28+
const ageSpan = document.getElementById('ageSpan');
29+
const addFiveBtn = document.getElementById('addFive');
30+
31+
// 1. 创建reducer整合函数
32+
// state表示当前状态,用于生成新状态 action保存操作信息的对象
33+
function reducer(state = { age: 18, name: 'sunshine'}, action) {
34+
switch (action.type) {
35+
case 'ADD':
36+
return { ...state, age: state.age + 1 };
37+
case 'SUB':
38+
return { ...state, age: state.age - 1 };
39+
case 'ADD_N':
40+
return { ...state, age: state.age + action.payload };
41+
default:
42+
return state;
43+
}
44+
}
45+
46+
// 2. 通过reducer对象创建store
47+
// const store = Redux.createStore(reducer);
48+
const store = Redux.createStore(reducer, { name: 'victor', age: 30 });
49+
50+
// 3. 对store中的state进行订阅
51+
store.subscribe(() => {
52+
console.log(store.getState());
53+
console.log(store.getState().name);
54+
ageSpan.innerText = store.getState().age;
55+
});
56+
57+
// 4. 通过dispatch派发state的操作指令
58+
subBtn.addEventListener('click', () => {
59+
store.dispatch({type: 'SUB'});
60+
});
61+
addBtn.addEventListener('click', () => {
62+
store.dispatch({type: 'ADD'});
63+
});
64+
addFiveBtn.addEventListener('click', () => {
65+
store.dispatch({type: 'ADD_N', payload: 5});
66+
});
67+
</script>
68+
69+
</body>
70+
</html>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /