{"id":346141,"date":"2023-03-02T09:01:30","date_gmt":"2023-03-02T09:01:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=346141"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=346141","title":{"rendered":"<span>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e React Table<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/wp\/1l\/vl\/wp1lvlefnz1iodhiom_q0oiiaay.png\" data-src=\"https:\/\/habrastorage.org\/webt\/wp\/1l\/vl\/wp1lvlefnz1iodhiom_q0oiiaay.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432 \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/react-table-v7.tanstack.com\/\">React Table<\/a>.<\/p>\n<p>  <\/p>\n<p>React Table \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u0434\u0435\u043d\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b <a href=\"https:\/\/ru.reactjs.org\/\">React<\/a> \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c 5 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0441 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0435\u0439;<\/li>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u0443\u044e.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0435\u0449\u0435 \u043e\u0431 \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0439 \u043b\u0435\u0433\u043a\u0438\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u0443\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0431\u043e\u0433\u0430\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0433\u043b\u0430\u0437\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0438\u043c\u0435\u0435\u0442\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u044b\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 React \u0438 <a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434, <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-table-test\">\u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e? \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u0414\u0435\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<p>React Table \u2014 &#171;\u0431\u0435\u0437\u0433\u043e\u043b\u043e\u0432\u0430\u044f&#187; (&#171;headless&#187;) \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u043b\u043e\u0433\u0438\u043a\u0443, \u0430 \u0437\u0430 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0438 \u0441\u0442\u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/overview\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/quick-start\">\u0417\u0434\u0435\u0441\u044c<\/a> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f React Table (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e).<\/p>\n<p>  <\/p>\n<h2 id=\"podgotovka-i-nastroyka-proekta\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/yarnpkg.com\/\">Yarn<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/vitejs.dev\/\">Vite<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\"># react-table-test - \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f # react-ts - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d: React + TypeScript yarn create vite react-table-test --template react-ts<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cd react-table-test yarn yarn dev<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\"># \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 yarn add react-table match-sorter react-icons @faker-js\/faker regenerator-runtime # \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 # \u0442\u0438\u043f\u044b \u0434\u043b\u044f Node.js \u0438 React Table yarn add -D @types\/node @types\/react-table<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/match-sorter\">match-sorter<\/a> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432;<\/li>\n<li><a href=\"https:\/\/react-icons.github.io\/react-icons\/\">react-icons<\/a> \u2014 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b-\u0438\u043a\u043e\u043d\u043a\u0438;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/@faker-js\/faker\">@faker-js\/faker<\/a> \u2014 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0438\u043a\u0442\u0438\u0432\u043d\u044b\u0445 (\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0441\u0442\u0438\u0447\u043d\u044b\u0445) \u0434\u0430\u043d\u043d\u044b\u0445;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/regenerator-runtime\">regenerator-runtime<\/a> \u2014 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u0430\u044f \u0441\u0440\u0435\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 <a href=\"https:\/\/www.npmjs.com\/package\/regenerator-runtime\">Regenerator<\/a>.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>regenerator-runtime<\/code> \u0432 \u0444\u0430\u0439\u043b\u0435 <code>main.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import 'regenerator-runtime'<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 React Table \u0438 React 18.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u0438\u043d\u043e\u043d\u0438\u043c\u044b \u043f\u0443\u0442\u0435\u0439 \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 <code>vite.config.ts<\/code> \u0438 <code>tsconfig.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ vite.config.ts import { defineConfig } from 'vite' import react from '@vitejs\/plugin-react' import { resolve } from 'node:path'  export default defineConfig({   plugins: [react()],   resolve: {     alias: {       '@': resolve(__dirname, '.\/src')     }   } })<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"json\">\/\/ tsconfig.json {   \"compilerOptions\": {     \/\/ ...     \"paths\": {       \"@\/*\": [         \".\/src\/*\"       ]     }   },   \/\/ ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code>, \u0438\u0437 <code>@\/*<\/code> \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>index.css<\/code> (\u0444\u0430\u0439\u043b <code>App.css<\/code> \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c):<\/p>\n<p>  <\/p>\n<pre><code class=\"css\">*, *::before, *::after {   box-sizing: border-box; }  body {   margin: 0; }  .table-wrapper {   overflow-x: auto; }  table {   width: 100%;   border-collapse: collapse; }  th, td {   white-space: nowrap;   padding: 0.5rem; }  th {   background: rgba(0, 0, 0, 0.1); }  tbody tr:nth-child(2n) {   background: rgba(0, 0, 0, 0.05); }  h1 {   text-align: center; }<\/code><\/pre>\n<p>  <\/p>\n<p>React Table \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u043f\u0440\u043e\u043f\u043e\u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438 \u044f\u0447\u0435\u0439\u043a\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0445\u0443\u043a\u043e\u0432 <code>useSortBy<\/code>, <code>useFilters<\/code> \u0438 \u0434\u0440. \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043a\u0430\u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a \u0438 \u0442.\u043f., \u0442.\u0435. \u043b\u044e\u0431\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u043a\u0440\u043e\u043c\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0434\u0430\u043b\u0435\u0435 \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0438\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u044c <code>react-table<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>types\/react-table-config.d.ts<\/code> (\u043f\u0443\u0442\u044c \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0432 \u0441\u0435\u0442\u0438 import {   UseColumnOrderInstanceProps,   UseColumnOrderState,   UseExpandedHooks,   UseExpandedInstanceProps,   UseExpandedOptions,   UseExpandedRowProps,   UseExpandedState,   UseFiltersColumnOptions,   UseFiltersColumnProps,   UseFiltersInstanceProps,   UseFiltersOptions,   UseFiltersState,   UseGlobalFiltersColumnOptions,   UseGlobalFiltersInstanceProps,   UseGlobalFiltersOptions,   UseGlobalFiltersState,   UseGroupByCellProps,   UseGroupByColumnOptions,   UseGroupByColumnProps,   UseGroupByHooks,   UseGroupByInstanceProps,   UseGroupByOptions,   UseGroupByRowProps,   UseGroupByState,   UsePaginationInstanceProps,   UsePaginationOptions,   UsePaginationState,   UseResizeColumnsColumnOptions,   UseResizeColumnsColumnProps,   UseResizeColumnsOptions,   UseResizeColumnsState,   UseRowSelectHooks,   UseRowSelectInstanceProps,   UseRowSelectOptions,   UseRowSelectRowProps,   UseRowSelectState,   UseRowStateCellProps,   UseRowStateInstanceProps,   UseRowStateOptions,   UseRowStateRowProps,   UseRowStateState,   UseSortByColumnOptions,   UseSortByColumnProps,   UseSortByHooks,   UseSortByInstanceProps,   UseSortByOptions,   UseSortByState } from 'react-table'  declare module 'react-table' {   \/\/ take this file as-is, or comment out the sections that don't apply to your plugin configuration   export interface TableOptions&lt;D extends object = {}>     extends UseExpandedOptions&lt;D>,       UseFiltersOptions&lt;D>,       UseGlobalFiltersOptions&lt;D>,       UseGroupByOptions&lt;D>,       UsePaginationOptions&lt;D>,       UseResizeColumnsOptions&lt;D>,       UseRowSelectOptions&lt;D>,       UseRowStateOptions&lt;D>,       UseSortByOptions&lt;D>,       \/\/ note that having Record here allows you to add anything to the options, this matches the spirit of the       \/\/ underlying js library, but might be cleaner if it's replaced by a more specific type that matches your       \/\/ feature set, this is a safe default.       Record&lt;string, any> {}    export interface Hooks&lt;D extends object = {}>     extends UseExpandedHooks&lt;D>,       UseGroupByHooks&lt;D>,       UseRowSelectHooks&lt;D>,       UseSortByHooks&lt;D> {}    export interface TableInstance&lt;D extends object = {}>     extends UseColumnOrderInstanceProps&lt;D>,       UseExpandedInstanceProps&lt;D>,       UseFiltersInstanceProps&lt;D>,       UseGlobalFiltersInstanceProps&lt;D>,       UseGroupByInstanceProps&lt;D>,       UsePaginationInstanceProps&lt;D>,       UseRowSelectInstanceProps&lt;D>,       UseRowStateInstanceProps&lt;D>,       UseSortByInstanceProps&lt;D> {}    export interface TableState&lt;D extends object = {}>     extends UseColumnOrderState&lt;D>,       UseExpandedState&lt;D>,       UseFiltersState&lt;D>,       UseGlobalFiltersState&lt;D>,       UseGroupByState&lt;D>,       UsePaginationState&lt;D>,       UseResizeColumnsState&lt;D>,       UseRowSelectState&lt;D>,       UseRowStateState&lt;D>,       UseSortByState&lt;D> {}    export interface ColumnInterface&lt;D extends object = {}>     extends UseFiltersColumnOptions&lt;D>,       UseGlobalFiltersColumnOptions&lt;D>,       UseGroupByColumnOptions&lt;D>,       UseResizeColumnsColumnOptions&lt;D>,       UseSortByColumnOptions&lt;D> {}    export interface ColumnInstance&lt;D extends object = {}>     extends UseFiltersColumnProps&lt;D>,       UseGroupByColumnProps&lt;D>,       UseResizeColumnsColumnProps&lt;D>,       UseSortByColumnProps&lt;D> {}    export interface Cell&lt;D extends object = {}, V = any>     extends UseGroupByCellProps&lt;D>,       UseRowStateCellProps&lt;D> {}    export interface Row&lt;D extends object = {}>     extends UseExpandedRowProps&lt;D>,       UseGroupByRowProps&lt;D>,       UseRowSelectRowProps&lt;D>,       UseRowStateRowProps&lt;D> {} }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>types\/index.ts<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import {   FilterProps,   UseGlobalFiltersInstanceProps,   UseGlobalFiltersOptions } from 'react-table'  export type GlobalFilterT&lt;T extends object> = (   props: Partial&lt;UseGlobalFiltersOptions&lt;T> &amp; UseGlobalFiltersInstanceProps&lt;T>> ) => JSX.Element  export type ColumnFilterT&lt;T extends object> = (   props: FilterProps&lt;T> ) => JSX.Element<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0438\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>utils\/getData.ts<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { faker } from '@faker-js\/faker'  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0447\u0438\u0441\u0435\u043b \u043e\u0442 0 \u0434\u043e `len` const range = (len: number) => {   const arr = []   for (let i = 0; i &lt; len; i++) {     arr.push(i)   }   return arr }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 id let _id = 1 const id = () => _id++  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0446\u0435\u043b\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 const randInt = (min: number, max: number) =>   Math.floor(min + Math.random() * (max - min + 1))  \/\/ \u0442\u0438\u043f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f export type User = ReturnType&lt;typeof createUser>  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f const createUser = () => {   const statusChance = Math.random()    return {     id: id(),     firstName: faker.name.firstName(),     lastName: faker.name.lastName(),     age: randInt(18, 65),     email: faker.internet.email(),     phone: faker.phone.number(),     address: {       city: faker.address.cityName(),       street: faker.address.streetAddress()     },     job: {       position: faker.name.jobTitle(),       company: faker.company.name()     },     visits: Math.floor(Math.random() * 100),     progress: Math.floor(Math.random() * 100),     status:       statusChance > 0.66         ? 'relationship'         : statusChance > 0.33           ? 'complicated'           : 'single'   } }  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0438\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b const getData = (len: number) => range(len).map(createUser)  export default getData<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">{   id: 1,   firstName: 'Germaine',   lastName: 'Ritchie',   age: 48,   email: 'Loy73@hotmail.com',   phone: '231.577.0194 x983',   address: {     city: 'Dallas',     street: '8906 Lelia Parks'   },   job: {     position: 'Lead Branding Facilitator',     company: 'Torphy - Klein'   },   visits: 54,   progress: 7,   status: 'relationship' }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>  <\/p>\n<h2 id=\"sortiruemaya-tablica\">\u0421\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/h2>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0445\u0443\u043a\u043e\u043c React Table \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/useTable\">useTable<\/a>, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useTable } from 'react-table'  const tableInstance = useTable(options)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>data: any[]<\/code> \u2014 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430;<\/li>\n<li><code>columns: Column[]<\/code> \u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u043a\u043e\u043b\u043e\u043d\u043e\u043a (column definitions).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>accessor: string | Function<\/code> \u2014 \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u043b\u043e\u043d\u043a\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0435\u0449\u0435 \u043e\u0434\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Header: string | Function<\/code> \u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u043a\u043e\u043b\u043e\u043d\u043a\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0439 \u043a\u043e\u043b\u043e\u043d\u043e\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const columns: Column&lt;User>[] = [   {     Header: 'First Name',     \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 `user['firstName']`     accessor: 'firstName',   },   {     Header: 'Company',     \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 - \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0430\u043d\u043d\u044b\u0445     \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 `user['job'].position in user['job'].company`     accessor: ({ job }) => `${job.position} in ${job.company}`   } ]<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0445\u0443\u043a <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/useSortBy\">useSortBy<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useTable, useSortBy } from 'react-table'  const tableInstance = useTable({ columns, data }, useSortBy)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043a\u043e\u043b\u043e\u043d\u043e\u043a, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>disableSortBy: true<\/code> \u2014 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u0441\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438);<\/li>\n<li><code>sortType: string | Function<\/code> \u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0430\u044f \u0442\u0438\u043f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438), \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438. \u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 (\u0442\u0438\u043f\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438) \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/TanStack\/table\/blob\/v7\/src\/sortTypes.js\">\u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435<\/a>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0438\u043f <code>alphanumeric<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>useSortBy()<\/code> \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>sortTypes: Record&lt;string, SortByFn><\/code> \u2014 \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 \u0432\u0438\u0434\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0442\u0440\u043e\u043a \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Sortable.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData, { User } from '@\/utils\/getData' import { BiSortAlt2, BiSortDown, BiSortUp } from 'react-icons\/bi' import { Column, SortByFn, useSortBy, useTable } from 'react-table'  \/\/ \u0434\u0430\u043d\u043d\u044b\u0435 const data = getData(20)  \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043e\u043d\u043e\u043a export const columns: Column&lt;User>[] = [   {     Header: 'ID',     \/\/ user['id']     accessor: 'id',     \/\/ \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443     disableSortBy: true   },   {     Header: 'First Name',     accessor: 'firstName',     \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438     sortType: 'string'   },   {     Header: 'Last Name',     accessor: 'lastName',     sortType: 'string'   },   {     Header: 'Age',     accessor: 'age',     sortType: 'number'   },   {     Header: 'Email',     accessor: 'email'   },   {     Header: 'Phone',     accessor: 'phone'   },   {     Header: 'Address',     \/\/ user['address'].city, user['address'].street     accessor: ({ address }) => `${address.city}, ${address.street}`   },   {     Header: 'Company',     accessor: ({ job }) => `${job.position} in ${job.company}`   } ]  \/\/ \u0442\u0438\u043f\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 const sortTypes: Record&lt;string, SortByFn&lt;User>> = {   \/\/ \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f `string`   string: (rowA, rowB, columnId, desc) => {     const [a, b] = [rowA.values[columnId], rowB.values[columnId]] as [       string,       string     ]      return a.localeCompare(b, 'en')   } }  export default function Sortable() {   \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b   const {     \/\/ \u044d\u0442\u0438 \u0448\u0442\u0443\u043a\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438     getTableProps,     getTableBodyProps,     \/\/ \u043e \u0442\u043e\u043c, \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u044b \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u0430 \u043d\u0435 \u0441\u0430\u043c\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435     headerGroups,     rows,     prepareRow   } = useTable({ columns, data, sortTypes }, useSortBy)    return (     &lt;>       &lt;h1>Sortable Table&lt;\/h1>       &lt;div className='table-wrapper'>         {\/* \u043a \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0435 \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u0432\u044b\u043a\u043d\u0443\u0442\u044c :) *\/}         &lt;table {...getTableProps()}>           &lt;thead>             {headerGroups.map((hG) => (               &lt;tr {...hG.getHeaderGroupProps()}>                 {hG.headers.map((col) => (                   &lt;th {...col.getHeaderProps(col.getSortByToggleProps())}>                     {col.render('Header')}{' '}                     {\/* \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439, \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0440\u044f\u0434\u043e\u043c \u0441 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0438\u043a\u043e\u043d\u043a\u0443 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043b\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 *\/}                     {col.canSort &amp;&amp; (                       &lt;span>                         {col.isSorted ? (                           col.isSortedDesc ? (                             &lt;BiSortUp \/>                           ) : (                             &lt;BiSortDown \/>                           )                         ) : (                           &lt;BiSortAlt2 \/>                         )}                       &lt;\/span>                     )}                   &lt;\/th>                 ))}               &lt;\/tr>             ))}           &lt;\/thead>           &lt;tbody {...getTableBodyProps()}>             {rows.map((row) => {               prepareRow(row)                return (                 &lt;tr {...row.getRowProps()}>                   {row.cells.map((cell) => (                     &lt;td {...cell.getCellProps()}>{cell.render('Cell')}&lt;\/td>                   ))}                 &lt;\/tr>               )             })}           &lt;\/tbody>         &lt;\/table>       &lt;\/div>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>App.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import Sortable from '.\/Table\/Sortable'  export default function App() {   return (     &lt;>       &lt;Sortable \/>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/0r\/iw\/jz\/0riwjz9gmlnehrmoz0eogjfbibi.png\" data-src=\"https:\/\/habrastorage.org\/webt\/0r\/iw\/jz\/0riwjz9gmlnehrmoz0eogjfbibi.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<h2 id=\"filtruemaya-tablica\">\u0424\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0445\u0443\u043a\u0438 <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/useGlobalFilter\">useGlobalFilter<\/a>\u0438 <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/useFilters\">useFilters<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useTable, useGlobalFilter, useFilters } from 'react-table'  const tableInstance = useTable({ columns, data }, useGlobalFilter, useFilters)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438, \u0442.\u0435. \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u0432\u0441\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c, \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043e\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Filter: Function<\/code> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 UI (\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430) \u0444\u0438\u043b\u044c\u0442\u0440\u0430;<\/li>\n<li><code>disableFilter: true<\/code> \u2014 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u0441\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c\u044b\u043c\u0438);<\/li>\n<li><code>filter: string | Function<\/code> \u2014 \u0441\u0442\u0440\u043e\u043a\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0430\u044f \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438), \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438. \u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 (\u0442\u0438\u043f\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438) \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/TanStack\/table\/blob\/v7\/src\/filterTypes.js\">\u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435<\/a>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0438\u043f <code>text<\/code>.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>filterTypes: FilterTypes<\/code> \u2014 \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0432 \u0432\u0438\u0434\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>defaultColumn: Object<\/code> \u2014 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430, \u0447\u0442\u043e \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 <code>Filter<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u043e\u043b\u043e\u043d\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <code>Table\/Filterable\/filters.ts<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { ColumnFilterT, GlobalFilterT } from '@\/types' import { User } from '@\/utils\/getData' import { matchSorter } from 'match-sorter' import { useMemo, useState } from 'react' import { FilterType, FilterTypes, useAsyncDebounce } from 'react-table'  \/\/ UI \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 export const GlobalFilter: GlobalFilterT&lt;User> = ({   preGlobalFilteredRows,   globalFilter,   setGlobalFilter }) => {   \/\/ \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a   const count = preGlobalFilteredRows?.length   \/\/ \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430   const [value, setValue] = useState(globalFilter as string)   \/\/ \u043c\u0435\u0442\u043e\u0434 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430   \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0432 250 \u043c\u0441   const onChange = useAsyncDebounce((value) => {     setGlobalFilter?.(value || undefined)   }, 250)    return (     &lt;label>       Search:{' '}       &lt;input         type='text'         value={value || ''}         onChange={(e) => {           setValue(e.target.value)           onChange(e.target.value)         }}         placeholder={`${count} records...`}       \/>     &lt;\/label>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ UI \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 export const DefaultColumnFilter: ColumnFilterT&lt;User> = ({   column: { filterValue, preFilteredRows, setFilter } }) => {   const count = preFilteredRows.length    return (     &lt;input       type='text'       value={filterValue || ''}       onChange={(e) => {         \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `undefined` \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430         setFilter(e.target.value || undefined)       }}       placeholder={`${count} records...`}     \/>   ) }  \/\/ UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430-\u0441\u043b\u0430\u0439\u0434\u0435\u0440\u0430 export const SliderColumnFilter: ColumnFilterT&lt;User> = ({   column: { filterValue, setFilter, preFilteredRows, id } }) => {   \/\/ \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   const [min, max] = useMemo(() => {     let min = preFilteredRows.length ? preFilteredRows[0].values[id] : 0     let max = min     preFilteredRows.forEach((r) => {       min = Math.min(r.values[id], min)       max = Math.max(r.values[id], max)     })     return [min, max]   }, [id, preFilteredRows])    return (     &lt;>       &lt;input         type='range'         min={min}         max={max}         value={filterValue || ''}         onChange={(e) => {           setFilter(parseInt(e.target.value, 10))         }}       \/>       &lt;button onClick={() => setFilter(undefined)}>Off&lt;\/button>       &lt;p>{filterValue}&lt;\/p>     &lt;\/>   ) }  \/\/ UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430-\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430 export const NumberRangeColumnFilter: ColumnFilterT&lt;User> = ({   column: { filterValue = [], preFilteredRows, setFilter, id } }) => {   const [min, max] = useMemo(() => {     let min = preFilteredRows.length ? preFilteredRows[0].values[id] : 0     let max = min     preFilteredRows.forEach((r) => {       min = Math.min(r.values[id], min)       max = Math.max(r.values[id], max)     })     return [min, max]   }, [id, preFilteredRows])    return (     &lt;div style={{ display: 'flex' }}>       &lt;input         type='number'         value={filterValue[0] || ''}         onChange={(e) => {           const val = e.target.value           setFilter((prev = []) => [             val ? parseInt(val, 10) : undefined,             prev[1]           ])         }}         placeholder={`Min ${min}`}       \/>       to       &lt;input         type='number'         value={filterValue[1] || ''}         onChange={(e) => {           const val = e.target.value           setFilter((prev = []) => [             prev[0],             val ? parseInt(val, 10) : undefined           ])         }}         placeholder={`Max ${max}`}       \/>     &lt;\/div>   ) }  \/\/ UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430-\u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0430 export const SelectColumnFilter: ColumnFilterT&lt;User> = ({   column: { filterValue, setFilter, preFilteredRows, id } }) => {   \/\/ \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b   const options = useMemo(() => {     const opts = new Set()     preFilteredRows.forEach((r) => {       opts.add(r.values[id])     })     return [...opts.values()]   }, [id, preFilteredRows])    return (     &lt;select       value={filterValue}       onChange={(e) => {         setFilter(e.target.value || undefined)       }}     >       &lt;option value=''>All&lt;\/option>       {options.map((o: any, i) => (         &lt;option value={o} key={i}>           {o}         &lt;\/option>       ))}     &lt;\/select>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 export const fuzzyText: FilterType&lt;User> = (rows, ids, filterValue) => {   return matchSorter(rows, filterValue, {     keys: [(row) => ids.map((id) => row.values[id]).flat()]   }) }  \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f fuzzyText.autoRemove = (val: unknown) => !val  \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 export const filterGreaterThanOrEqual: FilterType&lt;User> = (   rows,   ids,   filterValue ) => {   return rows.filter((row) => {     return ids.some((id) => {       const rowValue = row.values[id]       return rowValue >= filterValue     })   }) }  \/\/ \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0438\u0441\u043b\u043e\u043c filterGreaterThanOrEqual.autoRemove = (val: unknown) => typeof val !== 'number'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const filterTypes: FilterTypes&lt;User> = {   \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0442\u0438\u043f   fuzzyText,   \/\/ \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f `text`   \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043b\u0443\u0447\u0448\u0435   text: (rows, ids, filterVal) => {     return rows.filter((row) => {       return ids.some((id) => {         const rowVal = String(row.values[id])         return rowVal.toLowerCase().startsWith(String(filterVal).toLowerCase())       })     })   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Filterable\/index.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData, { User } from '@\/utils\/getData' import { Column, useFilters, useGlobalFilter, useTable } from 'react-table' import {   DefaultColumnFilter,   filterGreaterThanOrEqual,   filterTypes,   GlobalFilter,   NumberRangeColumnFilter,   SelectColumnFilter,   SliderColumnFilter } from '.\/filters'  const data = getData(20)  export const columns: Column&lt;User>[] = [   {     Header: 'ID',     accessor: 'id',     \/\/ \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e     disableFilters: true   },   {     Header: 'Name',     \/\/ \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438     \/\/ \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c `headerGroups`     columns: [       {         Header: 'First Name',         accessor: 'firstName'       },       {         Header: 'Last Name',         accessor: 'lastName',         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: 'fuzzyText'       }     ]   },   {     Header: 'Info',     columns: [       {         Header: 'Age',         accessor: 'age',         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430         Filter: SliderColumnFilter,         \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: 'equals'       },       {         Header: 'Visits',         accessor: 'visits',         Filter: NumberRangeColumnFilter,         filter: 'between'       },       {         Header: 'Status',         accessor: 'status',         Filter: SelectColumnFilter,         filter: 'includes'       },       {         Header: 'Profile Progress',         accessor: 'progress',         Filter: SliderColumnFilter,         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: filterGreaterThanOrEqual       }     ]   } ]  \/\/ \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e export const defaultColumn = {   Filter: DefaultColumnFilter,   \/\/ https:\/\/github.com\/TanStack\/table\/issues\/2293   filter: 'text' }  export default function Filterable() {   const {     getTableProps,     getTableBodyProps,     headerGroups,     rows,     prepareRow,     \/\/ \u043d\u043e\u0432\u044b\u0435 \u0448\u0442\u0443\u043a\u0438 (\u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c)     state,     visibleColumns,     preGlobalFilteredRows,     setGlobalFilter   } = useTable(     { columns, data, defaultColumn, filterTypes },     useGlobalFilter,     useFilters   )    return (     &lt;>       &lt;h1>Filterable Table&lt;\/h1>       &lt;div className='table-wrapper'>         &lt;table {...getTableProps()}>           &lt;thead>             {headerGroups.map((hG) => (               &lt;tr {...hG.getHeaderGroupProps()}>                 {hG.headers.map((col) => (                   &lt;th {...col.getHeaderProps()}>                     {col.render('Header')}                     {\/* \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u043c\u043e\u0439 *\/}                     {col.canFilter ? &lt;div>{col.render('Filter')}&lt;\/div> : null}                   &lt;\/th>                 ))}               &lt;\/tr>             ))}             &lt;tr>               &lt;th colSpan={visibleColumns.length}>                 {\/* \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 *\/}                 &lt;GlobalFilter                   preGlobalFilteredRows={preGlobalFilteredRows}                   globalFilter={state.globalFilter}                   setGlobalFilter={setGlobalFilter}                 \/>               &lt;\/th>             &lt;\/tr>           &lt;\/thead>           &lt;tbody {...getTableBodyProps()}>             {rows.map((row, i) => {               prepareRow(row)               return (                 &lt;tr {...row.getRowProps()}>                   {row.cells.map((cell) => (                     &lt;td {...cell.getCellProps()}>{cell.render('Cell')}&lt;\/td>                   ))}                 &lt;\/tr>               )             })}           &lt;\/tbody>         &lt;\/table>       &lt;\/div>       &lt;div>         {\/* \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a *\/}         &lt;p>Filtered rows count: {rows.length}&lt;\/p>         {\/* \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b *\/}         &lt;pre>           `{JSON.stringify(state.filters, null, 2)}`         &lt;\/pre>       &lt;\/div>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/wf\/ev\/bf\/wfevbfipbhdbjsr7vgg436p1cwc.png\" data-src=\"https:\/\/habrastorage.org\/webt\/wf\/ev\/bf\/wfevbfipbhdbjsr7vgg436p1cwc.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<h2 id=\"tablica-s-paginaciey\">\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0435\u0439<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0445\u0443\u043a <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/usePagination\">usePagination<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useTable, usePagination } from 'react-table'  const tableInstance = useTable({ columns, data }, usePagination)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0445\u0443\u043a\u0430 \u0432 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>page: Row[]<\/code> \u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0442\u0440\u043e\u043a (\u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0441\u0442\u0440\u043e\u043a \u0432\u043c\u0435\u0441\u0442\u043e <code>rows<\/code>);<\/li>\n<li><code>canPreviousPage: boolean<\/code> \u2014 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b;<\/li>\n<li><code>canNextPage: boolean<\/code> \u2014 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b;<\/li>\n<li><code>pageCount: number<\/code> \u2014 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446 (\u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0441\u0442\u0440\u043e\u043a);<\/li>\n<li><code>gotoPage: (pageIndex: number) => void<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 (\u043a \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0441\u0442\u0440\u043e\u043a \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c);<\/li>\n<li><code>nextPage: () => void<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435;<\/li>\n<li><code>previousPage: () => void<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435;<\/li>\n<li><code>setPageSize: (pageSize: number) => void<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0442\u0440\u043e\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435);<\/li>\n<li>\u0438 \u0434\u0440.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b (<code>state<\/code>) \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>pageIndex: number<\/code> \u2014 \u0438\u043d\u0434\u0435\u043a\u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b;<\/li>\n<li><code>pageSize: number<\/code> \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <code>initialState.pageSize<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Paginated\/Pagination.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { User } from '@\/utils\/getData' import React from 'react' import { TableInstance } from 'react-table'  type Props = Pick&lt;   TableInstance&lt;User>,   | 'gotoPage'   | 'previousPage'   | 'nextPage'   | 'canPreviousPage'   | 'canNextPage'   | 'pageCount'   | 'pageIndex'   | 'pageSize'   | 'setPageSize' >  export default function Pagination(props: Props) {   \/\/ \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435   const gotoFirstPage = () => props.gotoPage(0)   \/\/ \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435   const gotoLastPage = () => props.gotoPage(props.pageCount - 1)   \/\/ \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435   const gotoPage: React.ChangeEventHandler&lt;HTMLInputElement> = (e) => {     \/\/ \u0438\u043d\u0434\u0435\u043a\u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430     const page = e.target.value ? Number(e.target.value) - 1 : 0     props.gotoPage(page)   }   \/\/ \u043c\u0435\u0442\u043e\u0434 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b   const setPageSize: React.ChangeEventHandler&lt;HTMLSelectElement> = (e) => {     const size = Number(e.target.value)     props.setPageSize(size)   }    return (     &lt;div       style={{         display: 'flex',         justifyContent: 'space-between',         padding: '0 1rem'       }}     >       &lt;span>         &lt;button onClick={gotoFirstPage} disabled={!props.canPreviousPage}>           {'&lt;&lt;'}         &lt;\/button>         &lt;button onClick={props.previousPage} disabled={!props.canPreviousPage}>           {'&lt;'}         &lt;\/button>         &lt;button onClick={props.nextPage} disabled={!props.canNextPage}>           {'>'}         &lt;\/button>         &lt;button onClick={gotoLastPage} disabled={!props.canNextPage}>           {'>>'}         &lt;\/button>       &lt;\/span>       &lt;span>         Page {props.pageIndex + 1} of {props.pageCount}       &lt;\/span>       &lt;label>         Go to page:{' '}         &lt;input           type='number'           defaultValue={props.pageIndex + 1}           onChange={gotoPage}           style={{ width: '8ch' }}         \/>       &lt;\/label>       &lt;select value={props.pageSize} onChange={setPageSize}>         {[10, 20, 30].map((size) => (           &lt;option value={size} key={size}>             Show {size}           &lt;\/option>         ))}       &lt;\/select>     &lt;\/div>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Paginated\/index.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData from '@\/utils\/getData' import { usePagination, useTable } from 'react-table' \/\/ \u0431\u0435\u0440\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 import { columns } from '..\/Filterable' import Pagination from '.\/Pagination'  const data = getData(60)  export default function Paginated() {   const {     getTableProps,     getTableBodyProps,     headerGroups,     prepareRow,     \/\/ \u043d\u043e\u0432\u044b\u0435 \u0448\u0442\u0443\u043a\u0438     state: { pageIndex, pageSize },     page,     \/\/ \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0437\u0434\u0435\u0441\u044c \u0441\u0442\u043e\u0438\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c `...otherProps` :)     canPreviousPage,     canNextPage,     pageCount,     gotoPage,     nextPage,     previousPage,     setPageSize   } = useTable(     {       columns,       data,       \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b       initialState: {         pageSize: 10       }     },     usePagination   )    return (     &lt;>       &lt;h1>Paginated Table&lt;\/h1>       &lt;div className='table-wrapper'>         &lt;table {...getTableProps()}>           &lt;thead>             {headerGroups.map((hG) => (               &lt;tr {...hG.getHeaderGroupProps()}>                 {hG.headers.map((col) => (                   &lt;th {...col.getHeaderProps()}>{col.render('Header')}&lt;\/th>                 ))}               &lt;\/tr>             ))}           &lt;\/thead>           &lt;tbody {...getTableBodyProps()}>             {page.map((row, i) => {               prepareRow(row)               return (                 &lt;tr {...row.getRowProps()}>                   {row.cells.map((cell) => (                     &lt;td {...cell.getCellProps()}>{cell.render('Cell')}&lt;\/td>                   ))}                 &lt;\/tr>               )             })}           &lt;\/tbody>         &lt;\/table>       &lt;\/div>       &lt;br \/>       &lt;div>         {\/* \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u044f *\/}         &lt;Pagination           gotoPage={gotoPage}           canPreviousPage={canPreviousPage}           canNextPage={canNextPage}           pageCount={pageCount}           nextPage={nextPage}           previousPage={previousPage}           setPageSize={setPageSize}           pageIndex={pageIndex}           pageSize={pageSize}         \/>         {\/* \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 *\/}         &lt;pre>           `             {JSON.stringify(               {                 pageIndex,                 pageSize,                 pageCount,                 canNextPage,                 canPreviousPage               },               null,               2             )}           `         &lt;\/pre>       &lt;\/div>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/46\/jk\/1m\/46jk1mgekzrvty4xj9gtbg9ufgk.png\" data-src=\"https:\/\/habrastorage.org\/webt\/46\/jk\/1m\/46jk1mgekzrvty4xj9gtbg9ufgk.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p><em>\u0420\u0435\u043c\u0430\u0440\u043a\u0430:<\/em> \u043f\u043e\u0447\u0435\u043c\u0443 id \u0441\u0442\u0440\u043e\u043a \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 21? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0435 <code>columns<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0434 \u0444\u0430\u0439\u043b\u0430 <code>Table\/Filterable\/index.tsx<\/code>, \u0433\u0434\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 <code>const data = getData(20)<\/code>, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>_id<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>utils\/getData.ts<\/code>, \u0434\u043e 20.<\/p>\n<p>  <\/p>\n<h2 id=\"tablica-s-vozmozhnostyu-vybora-strok\">\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0445\u0443\u043a <a href=\"https:\/\/react-table-v7.tanstack.com\/docs\/api\/useRowSelect\">useRowSelect<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useTable, useRowSelect } from 'react-table'  const tableInstance = useTable({ columns, data }, useRowSelect)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0445\u0443\u043a\u0430 \u0432 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>selectedFlatRows: Row[]<\/code> \u2014 \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li><code>getToggleAllRowsSelectedProps<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u043f\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0438 \u0434\u0440.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b (<code>state<\/code>) \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>selectedRowIds<\/code>, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 id \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>getToggleRowSelectedProps<\/code>, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0441 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430\u043c\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>visibleColumns<\/code> \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0445\u0443\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f <code>useTable()<\/code> \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0445\u0443\u043a\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Selectable.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData, { User } from '@\/utils\/getData' import { forwardRef, useEffect, useRef } from 'react' import {   Row,   TableToggleAllRowsSelectedProps,   useRowSelect,   useTable } from 'react-table' \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b import { columns } from '.\/Sortable'  const data = getData(10)  \/\/ \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430 export const IndeterminateCheckbox = forwardRef(   (     { indeterminate, ...rest }: Partial&lt;TableToggleAllRowsSelectedProps>,     ref   ) => {     const defaultRef = useRef&lt;HTMLInputElement | null>(null)     const resolvedRef =       (ref as React.MutableRefObject&lt;HTMLInputElement | null>) || defaultRef      useEffect(() => {       if (resolvedRef.current) {         resolvedRef.current.indeterminate = indeterminate as boolean       }     }, [resolvedRef, indeterminate])      return &lt;input type='checkbox' ref={resolvedRef} {...rest} \/>   } )  export default function Selectable() {   const {     getTableProps,     getTableBodyProps,     headerGroups,     rows,     prepareRow,     \/\/ \u043d\u043e\u0432\u044b\u0435 \u0448\u0442\u0443\u043a\u0438     selectedFlatRows,     state: { selectedRowIds }   } = useTable({ columns, data }, useRowSelect, ({ visibleColumns }) => {     visibleColumns.push((cols) => [       \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a\u0438       {         id: 'selection',         \/\/ \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430         \/\/ \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u043a\u043e\u043b\u043e\u043d\u043a\u0438         Header: ({ getToggleAllRowsSelectedProps }) => (           &lt;IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} \/>         ),         \/\/ \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u044f\u0447\u0435\u0439\u043a\u0438         \/\/ \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u044f\u0447\u0435\u0439\u043a\u0438         Cell: ({ row }: { row: Row&lt;User> }) => (           &lt;IndeterminateCheckbox {...row.getToggleRowSelectedProps()} \/>         )       },       ...cols     ])   })    return (     &lt;>       &lt;h1>Selectable Table&lt;\/h1>       &lt;div className='table-wrapper'>         &lt;table {...getTableProps()}>           &lt;thead>             {headerGroups.map((hG) => (               &lt;tr {...hG.getHeaderGroupProps()}>                 {hG.headers.map((col) => (                   &lt;th {...col.getHeaderProps()}>{col.render('Header')} &lt;\/th>                 ))}               &lt;\/tr>             ))}           &lt;\/thead>           &lt;tbody {...getTableBodyProps()}>             {rows.map((row) => {               prepareRow(row)                return (                 &lt;tr {...row.getRowProps()}>                   {row.cells.map((cell) => (                     &lt;td {...cell.getCellProps()}>{cell.render('Cell')}&lt;\/td>                   ))}                 &lt;\/tr>               )             })}           &lt;\/tbody>         &lt;\/table>       &lt;\/div>       &lt;div>         {\/* \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a *\/}         &lt;p>Selected rows count: {Object.keys(selectedRowIds).length}&lt;\/p>         {\/* \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 *\/}         &lt;pre>           `             {JSON.stringify(               selectedFlatRows.map((d) => d.original),               null,               2             )}           `         &lt;\/pre>       &lt;\/div>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/-r\/2u\/jk\/-r2ujkbuwxazgq3ofmd5phpvvgc.png\" data-src=\"https:\/\/habrastorage.org\/webt\/-r\/2u\/jk\/-r2ujkbuwxazgq3ofmd5phpvvgc.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 React Table, \u043d\u043e \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u044d\u0442\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<p>  <\/p>\n<h2 id=\"kompleksnaya-tablica\">\u041a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0440\u0443\u0447\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0443\u043b\u044c\u0442\u0438\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438, \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 \u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Complex.tsx<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData, { User } from '@\/utils\/getData' import { BiSortAlt2, BiSortDown, BiSortUp } from 'react-icons\/bi' import {   Row,   useFilters,   useGlobalFilter,   usePagination,   useRowSelect,   useSortBy,   useTable,   Column } from 'react-table' \/\/ \u0442\u0438\u043f\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 import { sortTypes } from '.\/Sortable' \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438, \u0442\u0438\u043f\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 import {   filterGreaterThanOrEqual,   filterTypes,   GlobalFilter,   NumberRangeColumnFilter,   SelectColumnFilter,   SliderColumnFilter } from '.\/Filterable\/filters' \/\/ \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 import { defaultColumn } from '.\/Filterable' \/\/ \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 import Pagination from '.\/Paginated\/Pagination' \/\/ \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u0430 import { IndeterminateCheckbox } from '.\/Selectable'  \/\/ \u0434\u0430\u043d\u043d\u044b\u0435 const data = getData(60)  \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043e\u043d\u043e\u043a const columns: Column&lt;User>[] = [   {     Header: 'ID',     accessor: 'id',     \/\/ \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e     disableSortBy: true,     disableFilters: true   },   {     Header: 'Name',     columns: [       {         Header: 'First Name',         accessor: 'firstName',         \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438         sortType: 'string'       },       {         Header: 'Last Name',         accessor: 'lastName',         sortType: 'string',         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: 'fuzzyText'       }     ]   },   {     Header: 'Info',     columns: [       {         Header: 'Age',         accessor: 'age',         sortType: 'number',         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u0430         Filter: SliderColumnFilter,         \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: 'equals'       },       {         Header: 'Visits',         accessor: 'visits',         Filter: NumberRangeColumnFilter,         filter: 'between'       },       {         Header: 'Status',         accessor: 'status',         Filter: SelectColumnFilter,         filter: 'includes'       },       {         Header: 'Profile Progress',         accessor: 'progress',         Filter: SliderColumnFilter,         \/\/ \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438         filter: filterGreaterThanOrEqual       }     ]   } ]  export default function Complex() {   const {     \/\/ \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438     getTableProps,     getTableBodyProps,     headerGroups,     prepareRow,     \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435     state: { globalFilter, pageIndex, pageSize, filters },     \/\/ \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f     visibleColumns,     preGlobalFilteredRows,     setGlobalFilter,     \/\/ \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u044f     page,     canPreviousPage,     canNextPage,     pageCount,     gotoPage,     nextPage,     previousPage,     setPageSize,     \/\/ \u0432\u044b\u0431\u043e\u0440 \u0441\u0442\u0440\u043e\u043a     selectedFlatRows   } = useTable(     \/\/ \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438     {       columns,       data,       sortTypes,       defaultColumn,       filterTypes,       initialState: {         pageSize: 10       }     },     \/\/ \u043f\u043b\u0430\u0433\u0438\u043d\u044b     useGlobalFilter,     useFilters,     useSortBy,     usePagination,     useRowSelect,     \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0445\u0443\u043a\u0438     ({ visibleColumns }) => {       visibleColumns.push((cols) => [         {           id: 'selection',           Header: ({ getToggleAllRowsSelectedProps }) => (             &lt;IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} \/>           ),           Cell: ({ row }: { row: Row&lt;User> }) => (             &lt;IndeterminateCheckbox {...row.getToggleRowSelectedProps()} \/>           )         },         ...cols       ])     }   )    return (     &lt;>       &lt;h1>Complex Table&lt;\/h1>       &lt;div className='table-wrapper'>         &lt;table {...getTableProps()}>           &lt;thead>             {headerGroups.map((hG) => (               &lt;tr {...hG.getHeaderGroupProps()}>                 {hG.headers.map((col) => (                   &lt;th {...col.getHeaderProps(col.getSortByToggleProps())}>                     {col.render('Header')}                     {\/* \u0438\u043a\u043e\u043d\u043a\u0430 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 *\/}                     {col.canSort &amp;&amp; (                       &lt;span>                         {col.isSorted ? (                           col.isSortedDesc ? (                             &lt;BiSortUp \/>                           ) : (                             &lt;BiSortDown \/>                           )                         ) : (                           &lt;BiSortAlt2 \/>                         )}                       &lt;\/span>                     )}                     {\/* UI \u0444\u0438\u043b\u044c\u0442\u0440\u0430 *\/}                     {col.canFilter ? &lt;div>{col.render('Filter')}&lt;\/div> : null}                   &lt;\/th>                 ))}               &lt;\/tr>             ))}             &lt;tr>               &lt;th colSpan={visibleColumns.length}>                 {\/* \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 *\/}                 &lt;GlobalFilter                   preGlobalFilteredRows={preGlobalFilteredRows}                   globalFilter={globalFilter}                   setGlobalFilter={setGlobalFilter}                 \/>               &lt;\/th>             &lt;\/tr>           &lt;\/thead>           &lt;tbody {...getTableBodyProps()}>             {page.map((row) => {               prepareRow(row)                return (                 &lt;tr {...row.getRowProps()}>                   {row.cells.map((cell) => (                     &lt;td {...cell.getCellProps()}>{cell.render('Cell')}&lt;\/td>                   ))}                 &lt;\/tr>               )             })}           &lt;\/tbody>         &lt;\/table>       &lt;\/div>       &lt;br \/>       {\/* \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u044f *\/}       &lt;Pagination         gotoPage={gotoPage}         canPreviousPage={canPreviousPage}         canNextPage={canNextPage}         pageCount={pageCount}         nextPage={nextPage}         previousPage={previousPage}         setPageSize={setPageSize}         pageIndex={pageIndex}         pageSize={pageSize}       \/>       {\/* \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f *\/}       &lt;div>         {\/* \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b *\/}         &lt;p>Filters&lt;\/p>         &lt;pre>           `{JSON.stringify(filters, null, 2)}`         &lt;\/pre>         {\/* \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0438 *\/}         &lt;p>Pagination state&lt;\/p>         &lt;pre>           `             {JSON.stringify(               {                 pageIndex,                 pageSize,                 pageCount,                 canNextPage,                 canPreviousPage               },               null,               2             )}           `         &lt;\/pre>         {\/* \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 *\/}         &lt;p>Selected rows&lt;\/p>         &lt;pre>           `             {JSON.stringify(               selectedFlatRows.map((d) => d.original),               null,               2             )}           `         &lt;\/pre>       &lt;\/div>     &lt;\/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/_y\/el\/m1\/_yelm1hpjipiv85e3b23xmqeoly.png\" data-src=\"https:\/\/habrastorage.org\/webt\/_y\/el\/m1\/_yelm1hpjipiv85e3b23xmqeoly.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0432 \u0442\u043e\u0439 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 React Table. \u041c\u043d\u0435 \u043f\u0440\u0438\u0433\u043b\u044f\u043d\u0443\u043b\u0430\u0441\u044c <a href=\"https:\/\/www.material-react-table.com\/\">Material React Table<\/a>. <em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u043b\u0438\u0447\u0438\u0435 <a href=\"https:\/\/mui.com\/\">Material UI<\/a> 5 \u0432\u0435\u0440\u0441\u0438\u0438. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn add material-react-table @mui\/material @mui\/icons-material @emotion\/react @emotion\/styled<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 <code>Table\/Material.tsx<\/code> \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 (sic!):<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e, \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0443 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u043a\u0430\u0437\/\u0441\u043a\u0440\u044b\u0442\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432;<\/li>\n<li>\u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u044f \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0432\u044b\u0431\u043e\u0440 \u0441\u0442\u0440\u043e\u043a (\u0432\u0441\u0435\u0445 \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445);<\/li>\n<li>\u0441\u043a\u0440\u044b\u0442\u0438\u0435\/\u043f\u043e\u043a\u0430\u0437 \u043a\u043e\u043b\u043e\u043d\u043e\u043a;<\/li>\n<li>\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043b\u043e\u0442\u043d\u043e\u0441\u0442\u0438 (density) \u044f\u0447\u0435\u0435\u043a;<\/li>\n<li>\u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432 \u043f\u043e\u043b\u043d\u043e\u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0438 \u0434\u0440.<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">import getData, { User } from '@\/utils\/getData' import MaterialReactTable, { MRT_ColumnDef } from 'material-react-table'  const data = getData(40)  \/\/ \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 React Table export const columns: MRT_ColumnDef&lt;User>[] = [   {     header: 'ID',     accessorKey: 'id',     \/\/ \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e     enableSorting: false,     enableColumnFilter: false   },   {     header: 'First Name',     accessorKey: 'firstName'   },   {     header: 'Last Name',     accessorKey: 'lastName'   },   {     header: 'Age',     accessorKey: 'age'   },   {     header: 'Email',     accessorKey: 'email'   },   {     header: 'Phone',     accessorKey: 'phone'   },   {     header: 'Address',     accessorFn: ({ address }) => `${address.city}, ${address.street}`   },   {     header: 'Company',     accessorFn: ({ job }) => `${job.position} in ${job.company}`   } ]  export default function Material() {   \/\/ \u0432\u0443\u0430\u043b\u044f!   return (     &lt;MaterialReactTable       columns={columns}       data={data}       enableRowSelection       initialState={{ density: 'compact' }}     \/>   ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/_i\/qn\/yg\/_iqnyggiqe0elkv3tfixiegdsd0.png\" data-src=\"https:\/\/habrastorage.org\/webt\/_i\/qn\/yg\/_iqnyggiqe0elkv3tfixiegdsd0.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043a\u043e\u043d\u043e\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441: \u0437\u0430\u0447\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React Table, \u0435\u0441\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438? \u042d\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0432\u0438\u0434 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0447\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0442\u0435\u043c \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u0440\u043e\u0434\u0435 Material React Table, \u043e\u0431\u044b\u0447\u043d\u043e, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043a\u0430\u043a \u0435\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043e React Table. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u0443\u0437\u043d\u0430\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0438 \u043d\u0435 \u0437\u0440\u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0438 happy coding!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<p><a href=\"https:\/\/timeweb.cloud\/?utm_source=habr&amp;utm_medium=banner&amp;utm_campaign=vds-promo-6-rub\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/p-\/u9\/l2\/p-u9l27ynelxi92bcmdxhu76ma8.png\" data-src=\"https:\/\/habrastorage.org\/webt\/p-\/u9\/l2\/p-u9l27ynelxi92bcmdxhu76ma8.png\"\/><\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/719796\/\"> https:\/\/habr.com\/ru\/company\/timeweb\/blog\/719796\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/wp\/1l\/vl\/wp1lvlefnz1iodhiom_q0oiiaay.png\" data-src=\"https:\/\/habrastorage.org\/webt\/wp\/1l\/vl\/wp1lvlefnz1iodhiom_q0oiiaay.png\"\/>  <\/p>\n<p>  \u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u043f\u0440\u0438\u0435\u043c\u043e\u0432 \u043f\u043e \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/react-table-v7.tanstack.com\/\">React Table<\/a>.<\/p>\n<p>  <\/p>\n<p>React Table \u2014 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0441\u0430\u043c\u044b\u0445 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u0448\u043d\u0438\u0439 \u0434\u0435\u043d\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u044d\u043a\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u044b <a href=\"https:\/\/ru.reactjs.org\/\">React<\/a> \u0434\u043b\u044f \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0441\u0430\u043c\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0432 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0439\u0442\u0435, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c 5 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u0441 \u043f\u0430\u0433\u0438\u043d\u0430\u0446\u0438\u0435\u0439;<\/li>\n<li>\u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0442\u0440\u043e\u043a;<\/li>\n<li>\u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u0443\u044e.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0435\u0449\u0435 \u043e\u0431 \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0435\u0439 \u043b\u0435\u0433\u043a\u0438\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0440\u0443\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0431\u043e\u0433\u0430\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u0438 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0433\u043b\u0430\u0437\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0438\u043c\u0435\u0435\u0442\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u044b\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 React \u0438 <a href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434, <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-table-test\">\u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e? \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0448\u0443 \u043f\u043e\u0434 \u043a\u0430\u0442.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-346141","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346141","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=346141"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/346141\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=346141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=346141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=346141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}