如何绑定数据以做出反应 table
How to bind data to react table
我是第一次玩 React,我想连接(id、名称、状态和数量):
interface Goods {
id: number;
name: string;
status: string;
quantity?: number;
}
export const getGoods = (): Promise<Goods[]> => {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: "A",
status: "ready",
quantity: 15
},
{
id: 2,
name: "B",
status: "pending",
quantity: 25
},
{
id: 3,
name: "C",
status: "ready",
quantity: 10
},
{
id: 4,
name: "D",
status: "not ready",
quantity: 25
},
{
id: 5,
name: "E",
status: "ready",
quantity: 25
},
{
id: 6,
name: "F",
status: "ready",
quantity: 5
}
];
resolve(data);
}, 1000);
});
};
到table正文
:
import React from "react";
import { getGoods } from "./data";
export const Abc: React.FC = () => {
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">Quantity</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
);
};
顶部的樱桃也将进行排序(例如按照以下顺序:准备好、未准备好、待定)。
感谢您的帮助或提示!
这里是沙盒:
https://codesandbox.io/s/recursing-torvalds-c343o
在你的table体内做类似的事情
<div className="table">
{getGoods.data.map(goods=>(
<tr>
<td>{goods.id}</td>
<td>{goods.name}</td>
<td>{goods.status}</td>
<td>{goods.quantity}</td>
</tr>
)
)
}
</div>
正在加载数据
React 中的一切都围绕状态原则展开。您想使用 useState
挂钩将货物存储在状态中。
const [goods, setGoods] = React.useState<Goods[]>([]);
您将使用 useEffect
挂钩加载数据,并在 Promise
解析后将其保存到组件状态。你想要一个空的依赖数组 []
到 运行 效果只有一次。
React.useEffect(() => {
// need to define the function and call it separately
const load = async () => {
try {
const data = await getGoods();
setGoods(data);
} catch (error) {
// your Promise won't ever error, but an actual API might
}
};
load();
}, []);
在您的 table 中,您遍历 goods
数组并为每个数组呈现一个 table 行 tr
。 map
回调中的元素应该有一个唯一的 key
属性,所以我使用 id
作为键。 table 单元格 td
应遵循与您的列相同的顺序。
<tbody>
{goods.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.status}</td>
<td>{item.quantity}</td>
</tr>
))}
</tbody>
正在排序
为了排序,您需要额外的状态来存储排序 属性 和排序顺序(升序或降序)。大概是这样的:
const [sortProperty, setSortProperty] = React.useState<keyof Goods>("id");
const [isDesc, setIsDesc] = React.useState(false);
单击您的列标题将更新这些状态。您可以将 sortProperty
和 isDesc
的当前值应用于 goods
数组,以便在渲染之前获得有序数组。
也许我们想在再次点击当前排序的列时反转顺序,但在点击不同的列时使用升序作为第一个排序。我们可能会创建一个这样的函数,我们可以将其用作 th
元素的 onClick
处理程序。
const handleColumnClick = (name: keyof Goods) => {
const isCurrent = sortProperty === name;
setSortProperty(name);
setIsDesc(prev => isCurrent ? !prev : false);
}
<th scope="col" onClick={() => handleColumnClick("id")}>ID</th>
要应用订单,我们可以从 lodash's orderBy function 获得帮助。
const order = isDesc ? "desc" : "asc";
const rows = orderBy(goods, sortProperty, order);
我们想在 tbody
中使用这个有序变量 rows
而不是无序的 goods
.
组件代码
import React from "react";
import { getGoods, Goods } from "./data";
import { orderBy } from "lodash";
export const Question3: React.FC = () => {
const [goods, setGoods] = React.useState<Goods[]>([]);
const [sortProperty, setSortProperty] = React.useState<keyof Goods>("id");
const [isDesc, setIsDesc] = React.useState(false);
const handleColumnClick = (name: keyof Goods) => {
const isCurrent = sortProperty === name;
setSortProperty(name);
setIsDesc((prev) => (isCurrent ? !prev : false));
};
React.useEffect(() => {
// need to define the function and call it separately
const load = async () => {
try {
const data = await getGoods();
setGoods(data);
} catch (error) {
// your Promise won't ever error, but an actual API might
}
};
load();
}, []);
const order = isDesc ? "desc" : "asc";
const rows = orderBy(goods, sortProperty, order);
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col" onClick={() => handleColumnClick("id")}>
ID
</th>
<th scope="col" onClick={() => handleColumnClick("name")}>
Name
</th>
<th scope="col" onClick={() => handleColumnClick("status")}>
Status
</th>
<th scope="col" onClick={() => handleColumnClick("quantity")}>
Quantity
</th>
</tr>
</thead>
<tbody>
{rows.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.status}</td>
<td>{item.quantity}</td>
</tr>
))}
</tbody>
</table>
);
};
您的沙箱中有一个错误,混淆了默认导出和命名导出。应该是:
import {Question3 as Abc} from "./Table";
您还需要 export
您的 data.ts
文件中的 interface Goods
才能在您的组件中使用该类型。
getGoods 是承诺,需要时间来解决。直到那时显示加载器。
export const Abc: React.FC = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
useEffect(() => {
setLoading(true);
(async () => {
const dataResponse = await getGoods();
setData(dataResponse);
})().catch((e) => {
console.error(e)
}).finally(() => {
setLoading(false);
})
},[])
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">Quantity</th>
</tr>
</thead>
<tbody>
{loading && <tr>
<td colSpan='3'>Loading....</td>
</tr>}
{data.map(goods => (
<tr>
<td>{goods.id}</td>
<td>{goods.name}</td>
<td>{goods.status}</td>
<td>{goods.quantity}</td>
</tr>
))}
</tbody>
</table>
);
};
这将帮助您确保在
中获得最终数据
const [data, setData] = useState([]);
我们如何从承诺中获取数据?使用
useState(handler, []) // [] so that is get called only once per component
const dataResponse = await getGoods(); // wait till promise resolves
我是第一次玩 React,我想连接(id、名称、状态和数量):
interface Goods {
id: number;
name: string;
status: string;
quantity?: number;
}
export const getGoods = (): Promise<Goods[]> => {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: "A",
status: "ready",
quantity: 15
},
{
id: 2,
name: "B",
status: "pending",
quantity: 25
},
{
id: 3,
name: "C",
status: "ready",
quantity: 10
},
{
id: 4,
name: "D",
status: "not ready",
quantity: 25
},
{
id: 5,
name: "E",
status: "ready",
quantity: 25
},
{
id: 6,
name: "F",
status: "ready",
quantity: 5
}
];
resolve(data);
}, 1000);
});
};
到table正文
:import React from "react";
import { getGoods } from "./data";
export const Abc: React.FC = () => {
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">Quantity</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
);
};
顶部的樱桃也将进行排序(例如按照以下顺序:准备好、未准备好、待定)。
感谢您的帮助或提示!
这里是沙盒:
https://codesandbox.io/s/recursing-torvalds-c343o
在你的table体内做类似的事情
<div className="table">
{getGoods.data.map(goods=>(
<tr>
<td>{goods.id}</td>
<td>{goods.name}</td>
<td>{goods.status}</td>
<td>{goods.quantity}</td>
</tr>
)
)
}
</div>
正在加载数据
React 中的一切都围绕状态原则展开。您想使用 useState
挂钩将货物存储在状态中。
const [goods, setGoods] = React.useState<Goods[]>([]);
您将使用 useEffect
挂钩加载数据,并在 Promise
解析后将其保存到组件状态。你想要一个空的依赖数组 []
到 运行 效果只有一次。
React.useEffect(() => {
// need to define the function and call it separately
const load = async () => {
try {
const data = await getGoods();
setGoods(data);
} catch (error) {
// your Promise won't ever error, but an actual API might
}
};
load();
}, []);
在您的 table 中,您遍历 goods
数组并为每个数组呈现一个 table 行 tr
。 map
回调中的元素应该有一个唯一的 key
属性,所以我使用 id
作为键。 table 单元格 td
应遵循与您的列相同的顺序。
<tbody>
{goods.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.status}</td>
<td>{item.quantity}</td>
</tr>
))}
</tbody>
正在排序
为了排序,您需要额外的状态来存储排序 属性 和排序顺序(升序或降序)。大概是这样的:
const [sortProperty, setSortProperty] = React.useState<keyof Goods>("id");
const [isDesc, setIsDesc] = React.useState(false);
单击您的列标题将更新这些状态。您可以将 sortProperty
和 isDesc
的当前值应用于 goods
数组,以便在渲染之前获得有序数组。
也许我们想在再次点击当前排序的列时反转顺序,但在点击不同的列时使用升序作为第一个排序。我们可能会创建一个这样的函数,我们可以将其用作 th
元素的 onClick
处理程序。
const handleColumnClick = (name: keyof Goods) => {
const isCurrent = sortProperty === name;
setSortProperty(name);
setIsDesc(prev => isCurrent ? !prev : false);
}
<th scope="col" onClick={() => handleColumnClick("id")}>ID</th>
要应用订单,我们可以从 lodash's orderBy function 获得帮助。
const order = isDesc ? "desc" : "asc";
const rows = orderBy(goods, sortProperty, order);
我们想在 tbody
中使用这个有序变量 rows
而不是无序的 goods
.
组件代码
import React from "react";
import { getGoods, Goods } from "./data";
import { orderBy } from "lodash";
export const Question3: React.FC = () => {
const [goods, setGoods] = React.useState<Goods[]>([]);
const [sortProperty, setSortProperty] = React.useState<keyof Goods>("id");
const [isDesc, setIsDesc] = React.useState(false);
const handleColumnClick = (name: keyof Goods) => {
const isCurrent = sortProperty === name;
setSortProperty(name);
setIsDesc((prev) => (isCurrent ? !prev : false));
};
React.useEffect(() => {
// need to define the function and call it separately
const load = async () => {
try {
const data = await getGoods();
setGoods(data);
} catch (error) {
// your Promise won't ever error, but an actual API might
}
};
load();
}, []);
const order = isDesc ? "desc" : "asc";
const rows = orderBy(goods, sortProperty, order);
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col" onClick={() => handleColumnClick("id")}>
ID
</th>
<th scope="col" onClick={() => handleColumnClick("name")}>
Name
</th>
<th scope="col" onClick={() => handleColumnClick("status")}>
Status
</th>
<th scope="col" onClick={() => handleColumnClick("quantity")}>
Quantity
</th>
</tr>
</thead>
<tbody>
{rows.map((item) => (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.status}</td>
<td>{item.quantity}</td>
</tr>
))}
</tbody>
</table>
);
};
您的沙箱中有一个错误,混淆了默认导出和命名导出。应该是:
import {Question3 as Abc} from "./Table";
您还需要 export
您的 data.ts
文件中的 interface Goods
才能在您的组件中使用该类型。
getGoods 是承诺,需要时间来解决。直到那时显示加载器。
export const Abc: React.FC = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
useEffect(() => {
setLoading(true);
(async () => {
const dataResponse = await getGoods();
setData(dataResponse);
})().catch((e) => {
console.error(e)
}).finally(() => {
setLoading(false);
})
},[])
return (
<table className="table table-striped table-hover">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">Quantity</th>
</tr>
</thead>
<tbody>
{loading && <tr>
<td colSpan='3'>Loading....</td>
</tr>}
{data.map(goods => (
<tr>
<td>{goods.id}</td>
<td>{goods.name}</td>
<td>{goods.status}</td>
<td>{goods.quantity}</td>
</tr>
))}
</tbody>
</table>
);
};
这将帮助您确保在
中获得最终数据const [data, setData] = useState([]);
我们如何从承诺中获取数据?使用
useState(handler, []) // [] so that is get called only once per component
const dataResponse = await getGoods(); // wait till promise resolves