使用远程数据搜索不适用于 React material-table
Search not working with React material-table using remote data
我在这里 [1] 使用 material-table 模块和来自 Web 服务的远程数据。我已经包含了搜索参数,但它不起作用并且控制台中没有错误消息。
代码如下:
import React from 'react';
import ReactDOM from "react-dom";
import MaterialTable from 'material-table';
import { forwardRef } from 'react';
import AddBox from '@material-ui/icons/AddBox';
import ArrowUpward from '@material-ui/icons/ArrowUpward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Clear from '@material-ui/icons/Clear';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import Edit from '@material-ui/icons/Edit';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Remove from '@material-ui/icons/Remove';
import SaveAlt from '@material-ui/icons/SaveAlt';
import Search from '@material-ui/icons/Search';
import ViewColumn from '@material-ui/icons/ViewColumn';
const tableIcons = {
Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
SortArrow: forwardRef((props, ref) => <ArrowUpward {...props} ref={ref} />),
ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};
const GET_PUBLICATIONS_URL = 'http://193.62.54.159/backend/v1/publications?';
class App extends React.Component {
render() {
return (
<MaterialTable
icons={tableIcons}
title="Remote Data Preview"
columns={[
{ title: 'Publication ID', field: 'publicationId' },
{ title: 'PMID', field: 'pmid' },
{ title: 'First author', field: 'firstAuthor' },
{ title: 'Publication', field: 'title' },
{ title: 'Journal', field: 'journal' },
{ title: 'Status', field: 'status' },
]}
data={query =>
new Promise((resolve, reject) => {
// let url = 'https://reqres.in/api/users?'
let url = GET_PUBLICATIONS_URL
url += 'size=' + query.pageSize
url += '&page=' + (query.page)
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result._embedded.publications,
page: result.page.number,
totalCount: result.page.totalElements,
})
})
})
}
options={{
search: true
}}
/>
)
}
}
// export default DemoMUITable_RemoteData;
ReactDOM.render(<App />, document.getElementById("root"));
下面是上面使用的 Web 服务调用的输出示例:
{
_embedded: {
publications: [{
publicationId: "5d2dbec2483e4bcddc82c61c",
pmid: "jqfWof0a6N",
title: "hDoClFK1xW",
journal: "bsmw70kDBz",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "VRbSDd72mC",
email: "YgH4UoELBp"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbec2483e4bcddc82c61c?pmid=false"
}
}
},
{
publicationId: "5d2dbeff483e4bcddc82c61d",
pmid: "WlQsCFYg3b",
title: "bsthfcP7zY",
journal: "sUULVFkYJQ",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "UOTBdYbsRh",
email: "ZUmHQ7evjl"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbeff483e4bcddc82c61d?pmid=false"
}
}
},
{
publicationId: "5d2dbf05483e4bcddc82c61e",
pmid: "V1KphgdwaG",
title: "KoXVQJjoGp",
journal: "1bO9QNNDCM",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "KsfpbpEAGc",
email: "p69YIXvYEq"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbf05483e4bcddc82c61e?pmid=false"
}
}
},
{
publicationId: "5d2dbf0a483e4bcddc82c61f",
pmid: "JEmARsAgWM",
title: "CiOTlRIeD4",
journal: "l1ofJObwtJ",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "rGdQGN5oPh",
email: "6PI3NfrnmV"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbf0a483e4bcddc82c61f?pmid=false"
}
}
},
{
publicationId: "5d346e129bb39d8c6e33faa4",
pmid: "cNUmFPonBy",
title: "0LwQYP0fUK",
journal: "C3gQOWPZ2C",
firstAuthor: "q1LwUyYpgO",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "oJdt6ae7sp",
email: "jhdOF23b9m"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d346e129bb39d8c6e33faa4?pmid=false"
}
}
}
]
},
_links: {
first: {
href: "http://193.62.54.159/backend/v1/publications?page=0&size=5"
},
self: {
href: "http://193.62.54.159/backend/v1/publications"
},
next: {
href: "http://193.62.54.159/backend/v1/publications?page=1&size=5"
},
last: {
href: "http://193.62.54.159/backend/v1/publications?page=5&size=5"
}
},
page: {
size: 5,
totalElements: 26,
totalPages: 6,
number: 0
}
}
这是我的应用程序的依赖项:
"dependencies": {
"@material-ui/icons": "^4.2.1",
"material-table": "^1.40.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
查询对象包含一个搜索字段,它是当前的搜索值。您必须将其传递给您的在线查询并在后端对其进行过滤或在前端对其进行过滤,如下所示:
resolve({
data: result._embedded.publications.filter(pub => pub.firstAuthor.contains(query.search)),
page: result.page.number,
totalCount: result.page.totalElements,
})
如果你在前端过滤它,你应该编写你的自定义过滤函数来过滤所有相关字段,如名称、id 等。
对于来到这里寻找如何使用挂钩在 material-table 中进行服务器搜索的解决方案的任何人。
有一个错误(https://github.com/mbrn/material-table/pull/1611 破坏了搜索字段,因此请确保 material-table@1.60.0
codesandbox.io/s/material-table-server-search-on-hooks-tnniz
import React, { useEffect, useState } from "react";
import MaterialTable from "material-table";
import useAxios from "axios-hooks";
const MaterialTableSearchDemo = () => {
const [query, setQuery] = useState("");
const [items, setItems] = useState([]);
const [{ data = {}, loading }, runSearch] = useAxios(
`https://api.github.com/search/repositories?q=${query}&sort=stars&order=desc&type=Repositories`,
{ manual: true }
);
const columns = [
{ title: "Name", field: "name" },
{ title: "Stars", field: "stargazers_count" }
];
useEffect(() => {
if (query) {
runSearch();
} else {
setItems([]);
}
}, [query, runSearch]);
useEffect(() => {
if (!loading && Array.isArray(data.items)) {
setItems(data.items);
}
}, [loading, setItems, data.items]);
return (
<MaterialTable
title="Github repositories"
data={items}
columns={columns}
onSearchChange={setQuery}
options={{
debounceInterval: 500,
paging: false,
//searchAutoFocus: true
}}
localization={{
toolbar: {
searchPlaceholder: "e.g. React"
}
}}
isLoading={loading}
/>
);
};
export default MaterialTableSearchDemo;
如果要在table的所有行和列中搜索,可以使用下面的函数。
resolve({
data: result._embedded.publications.filter(function(obj) {
return Object.keys(obj).some(function(key) {
return obj[key] ? (obj[key]).toString().includes(query.search) : false;
})
}),
page: result.page.number,
totalCount: result.page.totalElements,
})
remoteSearch=(arr, searchKey)=>{
return arr.filter(function(obj) {
return Object.keys(obj).some(function(key) {
return obj[key] ? (obj[key]).toString().includes(searchKey) : false;
})
});
}
console.log(remoteSearch([{a:1},{b:"1"},{c:"test1"}],1))
我在这里 [1] 使用 material-table 模块和来自 Web 服务的远程数据。我已经包含了搜索参数,但它不起作用并且控制台中没有错误消息。
代码如下:
import React from 'react';
import ReactDOM from "react-dom";
import MaterialTable from 'material-table';
import { forwardRef } from 'react';
import AddBox from '@material-ui/icons/AddBox';
import ArrowUpward from '@material-ui/icons/ArrowUpward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Clear from '@material-ui/icons/Clear';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import Edit from '@material-ui/icons/Edit';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Remove from '@material-ui/icons/Remove';
import SaveAlt from '@material-ui/icons/SaveAlt';
import Search from '@material-ui/icons/Search';
import ViewColumn from '@material-ui/icons/ViewColumn';
const tableIcons = {
Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
SortArrow: forwardRef((props, ref) => <ArrowUpward {...props} ref={ref} />),
ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};
const GET_PUBLICATIONS_URL = 'http://193.62.54.159/backend/v1/publications?';
class App extends React.Component {
render() {
return (
<MaterialTable
icons={tableIcons}
title="Remote Data Preview"
columns={[
{ title: 'Publication ID', field: 'publicationId' },
{ title: 'PMID', field: 'pmid' },
{ title: 'First author', field: 'firstAuthor' },
{ title: 'Publication', field: 'title' },
{ title: 'Journal', field: 'journal' },
{ title: 'Status', field: 'status' },
]}
data={query =>
new Promise((resolve, reject) => {
// let url = 'https://reqres.in/api/users?'
let url = GET_PUBLICATIONS_URL
url += 'size=' + query.pageSize
url += '&page=' + (query.page)
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result._embedded.publications,
page: result.page.number,
totalCount: result.page.totalElements,
})
})
})
}
options={{
search: true
}}
/>
)
}
}
// export default DemoMUITable_RemoteData;
ReactDOM.render(<App />, document.getElementById("root"));
下面是上面使用的 Web 服务调用的输出示例:
{
_embedded: {
publications: [{
publicationId: "5d2dbec2483e4bcddc82c61c",
pmid: "jqfWof0a6N",
title: "hDoClFK1xW",
journal: "bsmw70kDBz",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "VRbSDd72mC",
email: "YgH4UoELBp"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbec2483e4bcddc82c61c?pmid=false"
}
}
},
{
publicationId: "5d2dbeff483e4bcddc82c61d",
pmid: "WlQsCFYg3b",
title: "bsthfcP7zY",
journal: "sUULVFkYJQ",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "UOTBdYbsRh",
email: "ZUmHQ7evjl"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbeff483e4bcddc82c61d?pmid=false"
}
}
},
{
publicationId: "5d2dbf05483e4bcddc82c61e",
pmid: "V1KphgdwaG",
title: "KoXVQJjoGp",
journal: "1bO9QNNDCM",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "KsfpbpEAGc",
email: "p69YIXvYEq"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbf05483e4bcddc82c61e?pmid=false"
}
}
},
{
publicationId: "5d2dbf0a483e4bcddc82c61f",
pmid: "JEmARsAgWM",
title: "CiOTlRIeD4",
journal: "l1ofJObwtJ",
firstAuthor: "NUed57buOd",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "rGdQGN5oPh",
email: "6PI3NfrnmV"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d2dbf0a483e4bcddc82c61f?pmid=false"
}
}
},
{
publicationId: "5d346e129bb39d8c6e33faa4",
pmid: "cNUmFPonBy",
title: "0LwQYP0fUK",
journal: "C3gQOWPZ2C",
firstAuthor: "q1LwUyYpgO",
publicationDate: "2019-07-16T12:07:01.937Z",
correspondingAuthor: {
authorName: "oJdt6ae7sp",
email: "jhdOF23b9m"
},
status: "ELIGIBLE",
_links: {
self: {
href: "http://193.62.54.159/backend/v1/publications/5d346e129bb39d8c6e33faa4?pmid=false"
}
}
}
]
},
_links: {
first: {
href: "http://193.62.54.159/backend/v1/publications?page=0&size=5"
},
self: {
href: "http://193.62.54.159/backend/v1/publications"
},
next: {
href: "http://193.62.54.159/backend/v1/publications?page=1&size=5"
},
last: {
href: "http://193.62.54.159/backend/v1/publications?page=5&size=5"
}
},
page: {
size: 5,
totalElements: 26,
totalPages: 6,
number: 0
}
}
这是我的应用程序的依赖项:
"dependencies": {
"@material-ui/icons": "^4.2.1",
"material-table": "^1.40.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "3.0.1"
},
查询对象包含一个搜索字段,它是当前的搜索值。您必须将其传递给您的在线查询并在后端对其进行过滤或在前端对其进行过滤,如下所示:
resolve({
data: result._embedded.publications.filter(pub => pub.firstAuthor.contains(query.search)),
page: result.page.number,
totalCount: result.page.totalElements,
})
如果你在前端过滤它,你应该编写你的自定义过滤函数来过滤所有相关字段,如名称、id 等。
对于来到这里寻找如何使用挂钩在 material-table 中进行服务器搜索的解决方案的任何人。
有一个错误(https://github.com/mbrn/material-table/pull/1611 破坏了搜索字段,因此请确保 material-table@1.60.0
codesandbox.io/s/material-table-server-search-on-hooks-tnniz
import React, { useEffect, useState } from "react";
import MaterialTable from "material-table";
import useAxios from "axios-hooks";
const MaterialTableSearchDemo = () => {
const [query, setQuery] = useState("");
const [items, setItems] = useState([]);
const [{ data = {}, loading }, runSearch] = useAxios(
`https://api.github.com/search/repositories?q=${query}&sort=stars&order=desc&type=Repositories`,
{ manual: true }
);
const columns = [
{ title: "Name", field: "name" },
{ title: "Stars", field: "stargazers_count" }
];
useEffect(() => {
if (query) {
runSearch();
} else {
setItems([]);
}
}, [query, runSearch]);
useEffect(() => {
if (!loading && Array.isArray(data.items)) {
setItems(data.items);
}
}, [loading, setItems, data.items]);
return (
<MaterialTable
title="Github repositories"
data={items}
columns={columns}
onSearchChange={setQuery}
options={{
debounceInterval: 500,
paging: false,
//searchAutoFocus: true
}}
localization={{
toolbar: {
searchPlaceholder: "e.g. React"
}
}}
isLoading={loading}
/>
);
};
export default MaterialTableSearchDemo;
如果要在table的所有行和列中搜索,可以使用下面的函数。
resolve({
data: result._embedded.publications.filter(function(obj) {
return Object.keys(obj).some(function(key) {
return obj[key] ? (obj[key]).toString().includes(query.search) : false;
})
}),
page: result.page.number,
totalCount: result.page.totalElements,
})
remoteSearch=(arr, searchKey)=>{
return arr.filter(function(obj) {
return Object.keys(obj).some(function(key) {
return obj[key] ? (obj[key]).toString().includes(searchKey) : false;
})
});
}
console.log(remoteSearch([{a:1},{b:"1"},{c:"test1"}],1))