(一)React Router 6 简介
1.Routes
- v6 新组件
- 作用和 v5 的
Switch
类似,用于Route
的容器 Route
只有一个会被匹配,且必须定义Routes
2.Route
component
、render
、children
都变了- 需要通过
element
来指定要挂载的组件
大约 4 分钟
Routes
Switch
类似,用于 Route
的容器Route
只有一个会被匹配,且必须定义 Routes
Route
component
、 render
、 children
都变了element
来指定要挂载的组件src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter as Router } from "react-router-dom";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Router>
<App />
</Router>,
);
useMemo()
解决 sum()
执行过慢导致 count
增加慢的问题useCallback()
缓存函数对象本身src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
React.memo()
是一个高阶组件
props
发生变化时才会重新渲染,否则总是返回缓存中的结果src/index.js
import ReactDOM from "react-dom/client";
import { App } from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
onAdd
导致 A
组件的 props
一定会变化, memo
无效,可以使用 useCallback()
useCallback()
是一个钩子函数,用来创建 React
中的回调函数
setState
fetch()
用于向服务器发送请求加载数据,是 Ajax
的升级版src/index.js
import ReactDOM from "react-dom/client";
import { App } from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
src/App.jsx
import React, { useEffect, useState } from "react";
import { StudentList } from "./components/StudentList";
import "./App.css";
// const STU_DATA = [
// {
// id: "1",
// attributes: {
// name: "张三",
// age: 18,
// gender: "男",
// address: "aaa",
// },
// },
// {
// id: "2",
// attributes: {
// name: "李四",
// age: 28,
// gender: "女",
// address: "bbb",
// },
// },
// {
// id: "3",
// attributes: {
// name: "王五",
// age: 38,
// gender: "男",
// address: "ccc",
// },
// },
// ];
export const App = () => {
// 学生数据
// const [stuData, setStuData] = useState(STU_DATA);
const [stuData, setStuData] = useState([]);
// 记录数据是否正在加载
const [loading, setLoading] = useState(false);
// 记录错误信息
const [error, setError] = useState(null);
useEffect(() => {
// 加载数据
setLoading(true);
setError(null);
fetch("http://localhost:1337/api/students")
.then((response) => {
return response.json();
})
.then((data) => {
setStuData(data.data);
setLoading(false);
})
.catch((err) => {
alert(err);
});
// 模拟请求出错
// fetch("http://localhost:1337/api/student")
// .then((response) => {
// // 判断是否正常返回响应信息
// if (response.ok) return response.json();
// // 没有成功加载到数据
// setLoading(false);
// // 抛出错误
// throw new Error("数据加载失败");
// })
// .then((data) => {
// setStuData(data.data);
// setLoading(false);
// })
// .catch((err) => {
// // catch一执行,说明上述代码出错了
// // 统一处理错误
// setLoading(false);
// setError(err);
// });
}, []);
return (
<div className="app">
{!loading && !error && <StudentList students={stuData} />}
{loading && <p>数据正在加载中...</p>}
{error && <p>数据加载异常!</p>}
</div>
);
};
src/App.jsx
import React, { useEffect, useState } from "react";
import { StudentList } from "./components/StudentList";
import "./App.css";
export const App = () => {
// 学生数据
const [stuData, setStuData] = useState([]);
// 记录数据是否正在加载
const [loading, setLoading] = useState(false);
// 记录错误信息
const [error, setError] = useState(null);
// useEffect()参数不能是异步函数
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
const res = await fetch("http://localhost:1337/api/students");
if (res.ok) {
const data = await res.json();
setStuData(data.data);
} else {
throw new Error("数据加载失败!");
}
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, []);
return (
<div className="app">
{!loading && !error && <StudentList students={stuData} />}
{loading && <p>数据正在加载中...</p>}
{error && <p>数据加载异常!</p>}
</div>
);
};
src/App.jsx
import React, { useCallback, useEffect, useState } from "react";
import { StudentList } from "./components/StudentList";
import StudentContext from "./store/StudentContext";
import "./App.css";
export const App = () => {
// 学生数据
const [stuData, setStuData] = useState([]);
// 记录数据是否正在加载
const [loading, setLoading] = useState(false);
// 记录错误信息
const [error, setError] = useState(null);
const fetchData = useCallback(async () => {
try {
setLoading(true);
setError(null);
const res = await fetch("http://localhost:1337/api/students");
if (res.ok) {
const data = await res.json();
setStuData(data.data);
} else {
throw new Error("数据加载失败!");
}
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
}, []);
// useEffect()参数不能是异步函数
useEffect(() => {
fetchData();
}, [fetchData]);
const loadData = () => {
fetchData();
};
return (
<StudentContext.Provider value={{ fetchData }}>
<div className="app">
<button onClick={loadData}>加载数据</button>
{!loading && !error && <StudentList students={stuData} />}
{loading && <p>数据正在加载中...</p>}
{error && <p>数据加载异常!</p>}
</div>
</StudentContext.Provider>
);
};
src/components/StudentList/index.jsx
import React from "react";
import Student from "../Student";
import StudentForm from "../StudentForm";
const StudentList = (props) => {
return (
<table>
<caption>学生列表</caption>
<thead>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>地址</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{props.students.map((stu) => {
return <Student key={stu.id} stu={stu} />;
})}
</tbody>
<tfoot>
<StudentForm />
</tfoot>
</table>
);
};
export default StudentList;