{"id":2964,"date":"2023-02-01T19:20:46","date_gmt":"2023-02-01T12:20:46","guid":{"rendered":"https:\/\/www.marketenterprise.vn\/blog\/?p=2964"},"modified":"2023-02-06T19:04:36","modified_gmt":"2023-02-06T12:04:36","slug":"gioi-thieu-ui-framework-rsuite-js","status":"publish","type":"post","link":"https:\/\/www.marketenterprise.vn\/blog\/gioi-thieu-ui-framework-rsuite-js.html","title":{"rendered":"Gi\u1edbi thi\u1ec7u v\u1ec1 UI Framework RSuite JS b\u1ea1n n\u00ean bi\u1ebft"},"content":{"rendered":"<h2>H\u00e3y c\u00f9ng t\u00ecm hi\u1ec3u React l\u00e0 g\u00ec?<\/h2>\n<p><span style=\"font-weight: 400;\">React l\u00e0 m\u1ed9t th\u01b0 vi\u1ec7n Javascript open-source h\u00e0ng \u0111\u1ea7u gi\u00fap b\u1ea1n x\u00e2y d\u1ef1ng giao di\u1ec7n d\u00e0nh cho c\u1ea3 web c\u0169ng nh\u01b0 c\u00e1c \u1ee9ng d\u1ee5ng tr\u00ean thi\u1ebft b\u1ecb di \u0111\u1ed9ng. React d\u1ec5 d\u00e0ng k\u1ebft h\u1ee3p v\u1edbi c\u00e1c th\u01b0 vi\u1ec7n v\u00e0 framework Javascript kh\u00e1c. \u0110\u1ec3 x\u00e2y d\u1ef1ng UI b\u1eb1ng React ch\u00fang ta s\u1eed d\u1ee5ng c\u00e1c \u0111o\u1ea1n code nh\u1ecf, \u0111\u1ed9c l\u1eadp \u0111\u01b0\u1ee3c g\u1ecdi l\u00e0 <\/span><i><span style=\"font-weight: 400;\">components<\/span><\/i><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h2>UI Framework RSuite JS<\/h2>\n<p><span style=\"font-weight: 400;\">RSuite (<\/span><a href=\"https:\/\/rsuitejs.com\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">React Suite)<\/span><\/a><span style=\"font-weight: 400;\"> l\u00e0 m\u1ed9t th\u01b0 vi\u1ec7n React components th\u00edch h\u1ee3p cho vi\u1ec7c x\u00e2y d\u1ef1ng c\u00e1c \u1ee9ng d\u1ee5ng web, \u0111\u1eb7c bi\u1ec7t l\u00e0 c\u00e1c trang qu\u1ea3n l\u00fd d\u00e0nh cho c\u00e1c doanh nghi\u1ec7p v\u1eeba v\u00e0 nh\u1ecf. C\u00e1c \u0111i\u1ec3m m\u1ea1nh c\u1ee7a RSuite bao g\u1ed3m: thi\u1ebft k\u1ebf giao di\u1ec7n th\u00e2n thi\u1ec7n v\u1edbi user, d\u1ec5 d\u00e0ng ch\u1ec9nh s\u1eeda, \u0111a d\u1ea1ng c\u00e1c lo\u1ea1i components\u2026<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Khi x\u00e2y d\u1ef1ng m\u1ed9t \u1ee9ng d\u1ee5ng web b\u1eb1ng React, c\u00e1c developers th\u01b0\u1eddng g\u1eb7p ph\u1ea3i nh\u1eefng UI ho\u1eb7c t\u00ednh n\u0103ng t\u01b0\u01a1ng t\u1ef1 nhau. Thay v\u00ec x\u00e2y d\u1ef1ng c\u00e1c components n\u00e0y t\u1eeb \u0111\u1ea7u th\u00ec ch\u00fang ta c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng m\u1ed9t UI <a href=\"https:\/\/www.marketenterprise.vn\/blog\/framework-tailwind-css.html\">Framework<\/a>, \u0111i\u1ec1u n\u00e0y gi\u00fap t\u0103ng t\u1ed1c \u0111\u1ed9 develop c\u0169ng nh\u01b0 h\u1ea1n ch\u1ebf bug. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Theo l\u1eddi c\u00e1c developers c\u1ee7a React Suite, \u201c\u0110\u00e2y l\u00e0 m\u1ed9t b\u1ed9 (suite) c\u00e1c React components v\u1edbi UI \u0111\u00e3 \u0111\u01b0\u1ee3c nghi\u00ean c\u1ee9u v\u00e0 thi\u1ebft k\u1ebf m\u1ed9t c\u00e1ch h\u1ee3p l\u00fd, mang \u0111\u1ebfn tr\u1ea3i nghi\u1ec7m th\u00e2n thi\u1ec7n cho developer c\u0169ng nh\u01b0 end-user\u201d. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Trong th\u1ef1c t\u1ebf,\u00a0 React Suite \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf v\u00e0 tri\u1ec3n khai \u0111\u1ec3 s\u1eed d\u1ee5ng tr\u00ean desktop browsers thay v\u00ec mobile browsers. V\u00ec v\u1eady, trong b\u00e0i vi\u1ebft n\u00e0y, ch\u00fang ta s\u1ebd c\u00f9ng t\u00ecm hi\u1ec3u v\u00e0 x\u00e2y d\u1ef1ng m\u1ed9t \u1ee9ng d\u1ee5ng Todo App b\u1eb1ng RSuite JS.<\/span><\/p>\n<h2>T\u1ed5ng quan v\u1ec1 \u1ee9ng d\u1ee5ng m\u00e0 ch\u00fang ta s\u1ebd x\u00e2y d\u1ef1ng<\/h2>\n<p><span style=\"font-weight: 400;\">Trong khu\u00f4n kh\u1ed5 b\u00e0i vi\u1ebft, ch\u00fang ta s\u1ebd x\u00e2y d\u1ef1ng m\u1ed9t Todo App s\u1eed d\u1ee5ng React k\u1ebft h\u1ee3p v\u1edbi th\u01b0 vi\u1ec7n UI Component RSuite. \u1ee8ng d\u1ee5ng cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng t\u1ea1o v\u00e0 c\u1eadp nh\u1eadt danh s\u00e1ch c\u00e1c vi\u1ec7c c\u1ea7n l\u00e0m. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Th\u00f4ng qua v\u00ed d\u1ee5 n\u00e0y, hy v\u1ecdng c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 bi\u1ebft c\u00e1ch s\u1eed d\u1ee5ng m\u1ed9t th\u01b0 vi\u1ec7n UI Component \u0111\u1ec3 x\u00e2y d\u1ef1ng \u1ee9ng d\u1ee5ng, t\u1eeb \u0111\u00f3 \u00e1p d\u1ee5ng cho c\u00e1c th\u01b0 vi\u1ec7n t\u01b0\u01a1ng t\u1ef1 nh\u01b0: Ant Design, Headless UI, React Bootstrap,&#8230;<\/span><\/p>\n<h2>C\u00e1c b\u01b0\u1edbc th\u1ef1c hi\u1ec7n b\u1ea1n c\u1ea7n bi\u1ebft<\/h2>\n<h3>T\u1ea1o m\u1ed9t d\u1ef1 \u00e1n m\u1edbi v\u1edbi Create React App v\u00e0 c\u00e0i \u0111\u1eb7t RSuite<\/h3>\n<p><span style=\"font-weight: 400;\">Ch\u00fang ta h\u00e3y b\u1eaft \u0111\u1ea7u b\u1eb1ng c\u00e1ch thi\u1ebft l\u1eadp d\u1ef1 \u00e1n m\u1edbi. Ch\u1ea1y l\u1ec7nh b\u00ean d\u01b0\u1edbi \u0111\u1ec3 t\u1ea1o React project:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">npx create-react-app react-suite-app &amp;&amp; cd react-suite-app<\/pre>\n<p><span style=\"font-weight: 400;\">L\u1ec7nh tr\u00ean s\u1ebd t\u1ea1o m\u1ed9t th\u01b0 m\u1ee5c m\u1edbi t\u00ean l\u00e0 react-suite-app. B\u00ean trong th\u01b0 m\u1ee5c n\u00e0y, l\u1ec7nh create-react-app \u0111\u00e3 t\u1ea1o ra c\u1ea5u tr\u00fac m\u1eb7c \u0111\u1ecbnh c\u1ee7a d\u1ef1 \u00e1n v\u00e0 c\u00e0i \u0111\u1eb7t c\u00e1c th\u01b0 vi\u1ec7n li\u00ean quan. B\u00e2y gi\u1edd h\u00e3y m\u1edf project v\u1eeba \u0111\u01b0\u1ee3c t\u1ea1o b\u1eb1ng text editor y\u00eau th\u00edch c\u1ee7a b\u1ea1n. \u0110\u1ed1i v\u1edbi c\u00e1c minh h\u1ecda trong b\u00e0i vi\u1ebft n\u00e0y, ch\u00fang ta s\u1ebd s\u1eed d\u1ee5ng Visual Studio Code.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Sau khi \u0111\u00e3 di chuy\u1ec3n v\u00e0o b\u00ean trong th\u01b0 m\u1ee5c v\u1eeba \u0111\u01b0\u1ee3c t\u1ea1o, ch\u1ea1y l\u1ec7nh sau \u0111\u1ec3 m\u1edf d\u1ef1 \u00e1n b\u1eb1ng VSCode:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">code .<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193935\/2-246x300.png\" alt=\"2. React Suite\" width=\"246\" height=\"300\" class=\"size-medium wp-image-2967 aligncenter\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193935\/2-246x300.png 246w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193935\/2.png 315w\" sizes=\"auto, (max-width: 246px) 100vw, 246px\" \/><\/p>\n<h3><span style=\"font-weight: 400;\">Ti\u1ebfp theo, ch\u00fang ta s\u1ebd ch\u1ea1y l\u1ec7nh sau \u0111\u1ec3 c\u00e0i \u0111\u1eb7t RSuite:<\/span><\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">yarn add rsuite<\/pre>\n<p><strong>Sau khi vi\u1ec7c c\u00e0i \u0111\u1eb7t ho\u00e0n t\u1ea5t, ch\u1ea1y l\u1ec7nh b\u00ean d\u01b0\u1edbi \u0111\u1ec3 ch\u1ea1y application tr\u00ean browser:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">yarn start<\/pre>\n<p><strong>N\u1ebfu b\u1ea1n m\u1edf application tr\u00ean browser c\u1ee7a m\u00ecnh, b\u1ea1n s\u1ebd th\u1ea5y m\u00e0n h\u00ecnh hi\u1ec3n th\u1ecb nh\u01b0 b\u00ean d\u01b0\u1edbi:<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193938\/3-300x194.png\" alt=\"3. Attachment details\" width=\"300\" height=\"194\" class=\"size-medium wp-image-2968 aligncenter\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193938\/3-300x194.png 300w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193938\/3-1024x663.png 1024w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193938\/3-768x497.png 768w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193938\/3.png 1332w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Nh\u01b0 v\u1eady l\u00e0 ch\u00fang ta \u0111\u00e3 t\u1ea1o xong d\u1ef1 \u00e1n m\u1edbi v\u00e0 c\u00e0i \u0111\u1eb7t c\u00e1c th\u01b0 vi\u1ec7n c\u1ea7n thi\u1ebft. Ph\u1ea7n ti\u1ebfp theo, m\u00ecnh v\u00e0 c\u00e1c b\u1ea1n s\u1ebd b\u1eaft \u0111\u1ea7u code c\u00e1c UI c\u1ea7n thi\u1ebft cho Todo App. <\/span><\/p>\n<h3>T\u1ea1o layout c\u01a1 b\u1ea3n cho Todo App<\/h3>\n<p><span style=\"font-weight: 400;\">\u0110\u1ea7u ti\u00ean, ch\u00fang ta s\u1ebd t\u1ea1o giao di\u1ec7n t\u1ed5ng quan cho Todo App, bao g\u1ed3m:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Thanh navigation bar<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Khu v\u1ef1c main content \u0111\u1ec3 ch\u1ee9a form nh\u1eadp c\u00f4ng vi\u1ec7c c\u1ea7n l\u00e0m m\u1edbi c\u0169ng nh\u01b0 danh s\u00e1ch c\u00e1c c\u00f4ng vi\u1ec7c c\u1ea7n l\u00e0m<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">M\u1edf file<\/span><i><span style=\"font-weight: 400;\"> .\/src\/App.js<\/span><\/i><span style=\"font-weight: 400;\"> v\u00e0 ch\u1ec9nh s\u1eeda nh\u01b0 sau:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">import React from \"react\";\r\nimport { Container, Header, Navbar, Nav, Content } from \"rsuite\";\r\nimport CogIcon from \"@rsuite\/icons\/legacy\/Cog\";\r\nimport \"rsuite\/dist\/rsuite.min.css\";\r\nimport \".\/App.css\";\r\n\r\nconst App = () =&gt; {\r\n  const [activeKey, setActiveKey] = React.useState(1)<\/pre>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"> return (\r\n    &lt;div className=\"main\"&gt;\r\n      &lt;Container&gt;\r\n        &lt;Header&gt;\r\n          &lt;Navbar appearance=\"inverse\"&gt;\r\n            &lt;Navbar.Brand href=\"#\"&gt;RSUITE&lt;\/Navbar.Brand&gt;\r\n            &lt;Nav onSelect={setActiveKey} activeKey={activeKey}&gt;\r\n              &lt;Nav.Item eventKey=\"1\"&gt;Todo&lt;\/Nav.Item&gt;\r\n            &lt;\/Nav&gt;\r\n            &lt;Nav pullRight&gt;\r\n              &lt;Nav.Item icon={&lt;CogIcon \/&gt;}&gt;Settings&lt;\/Nav.Item&gt;\r\n            &lt;\/Nav&gt;\r\n          &lt;\/Navbar&gt;\r\n        &lt;\/Header&gt;\r\n        &lt;Content&gt;\r\n          &lt;FlexboxGrid justify=\"center\"&gt;\r\n            &lt;FlexboxGrid.Item colspan={12}&gt;\r\n            &lt;\/FlexboxGrid.Item&gt;\r\n          &lt;\/FlexboxGrid&gt;\r\n        &lt;\/Content&gt;\r\n      &lt;\/Container&gt;\r\n    &lt;\/div&gt;\r\n  );\r\n};\r\n\r\nexport default App;\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">Trong \u0111o\u1ea1n code tr\u00ean, ch\u00fang ta \u0111\u00e3 import CSS b\u1ea3n r\u00fat g\u1ecdn (minified) c\u1ee7a React Suite, \u0111\u00e2y l\u00e0 file ch\u1ee9a CSS d\u00e0nh cho c\u00e1c component c\u1ee7a RSuite.<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">import \"rsuite\/dist\/rsuite.min.css\";<\/pre>\n<p><span style=\"font-weight: 400;\">Ti\u1ebfp theo, ch\u00fang ta s\u1eed d\u1ee5ng c\u00e1c component \u0111\u01b0\u1ee3c RSuite cung c\u1ea5p s\u1eb5n \u0111\u1ec3 nhanh ch\u00f3ng ho\u00e0n thi\u1ec7n ph\u1ea7n UI mong mu\u1ed1n:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">C\u00e1c components \u0111\u01b0\u1ee3c import bao g\u1ed3m:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/rsuitejs.com\/components\/container\/#container\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Container<\/span><\/a><span style=\"font-weight: 400;\">: \u0111\u1ecbnh ngh\u0129a frame cho trang<\/span><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/rsuitejs.com\/components\/navbar\/#navbar\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Navbar<\/span><\/a><span style=\"font-weight: 400;\">: th\u00eam navigation v\u00e0o trang<\/span><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/rsuitejs.com\/components\/nav\/#nav\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Nav<\/span><\/a><span style=\"font-weight: 400;\">: th\u00eam danh s\u00e1ch navigation menu\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/rsuitejs.com\/components\/container\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Header<\/span><\/a><span style=\"font-weight: 400;\">: th\u00eam ti\u00eau \u0111\u1ec1 v\u00e0o trang<\/span><\/li>\n<li style=\"font-weight: 400;\"><a href=\"https:\/\/rsuitejs.com\/components\/container\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Content<\/span><\/a><span style=\"font-weight: 400;\">: \u0111\u1ecbnh ngh\u0129a n\u1ed9i dung c\u1ee7a trang<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">L\u01b0u file v\u1eeba ch\u1ec9nh s\u1eeda v\u00e0 quay l\u1ea1i browser, b\u1ea1n s\u1ebd th\u1ea5y k\u1ebft qu\u1ea3 nh\u01b0 sau:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193944\/4-300x197.png\" alt=\"4. Attachment details\" width=\"300\" height=\"197\" class=\"size-medium wp-image-2969 aligncenter\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193944\/4-300x197.png 300w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193944\/4-1024x673.png 1024w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193944\/4-768x504.png 768w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193944\/4.png 1317w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Th\u1eadt l\u00e0 nhanh ch\u00f3ng \u0111\u1ec3 c\u00f3 m\u1ed9t UI c\u01a1 b\u1ea3n \u0111\u00fang kh\u00f4ng n\u00e0o? Ti\u1ebfp theo ch\u00fang ta s\u1ebd s\u1eed d\u1ee5ng c\u00e1c component trong th\u01b0 vi\u1ec7n \u0111\u1ec3 x\u00e2y d\u1ef1ng form nh\u1eadp t\u00ean c\u1ee7a c\u00f4ng vi\u1ec7c (Todo) m\u1edbi.<\/span><\/p>\n<h3>T\u1ea1o Todo Form<\/h3>\n<p><span style=\"font-weight: 400;\">Ch\u00fang ta s\u1ebd t\u1ea1o <\/span><i><span style=\"font-weight: 400;\">TodoForm<\/span><\/i><span style=\"font-weight: 400;\"> component \u0111\u1ec3 ng\u01b0\u1eddi d\u00f9ng nh\u1eadp n\u1ed9i dung vi\u1ec7c c\u1ea7n l\u00e0m (Todo) m\u1edbi. T\u1ea1o folder m\u1edbi t\u00ean l\u00e0 <\/span><b><i>components<\/i><\/b><span style=\"font-weight: 400;\"> b\u00ean trong folder <\/span><b><i>src<\/i><\/b><span style=\"font-weight: 400;\">. B\u00ean trong folder <\/span><b><i>components<\/i><\/b><span style=\"font-weight: 400;\"> v\u1eeba t\u1ea1o, t\u1ea1o m\u1ed9t folder m\u1edbi t\u00ean l\u00e0 <\/span><b><i>todos<\/i><\/b><span style=\"font-weight: 400;\"> v\u00e0 file <\/span><b><i>TodoForm.js<\/i><\/b><span style=\"font-weight: 400;\"> v\u1edbi \u0111o\u1ea1n code nh\u01b0 sau:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193946\/5-300x64.png\" alt=\"5. Edit Image\" width=\"300\" height=\"64\" class=\"alignnone size-medium wp-image-2970\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193946\/5-300x64.png 300w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193946\/5.png 315w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">import React from \"react\";\r\nimport { FlexboxGrid, Panel, Form, ButtonToolbar, Button } from \"rsuite\";\r\n\r\nconst TodoForm = () =&gt; {\r\n  return (\r\n    &lt;Panel header={&lt;h3&gt;Add ToDo&lt;\/h3&gt;} bordered&gt;\r\n      &lt;Form fluid&gt;\r\n        &lt;Form.Group&gt;\r\n          &lt;Form.ControlLabel&gt;What you want to do?&lt;\/Form.ControlLabel&gt;\r\n          &lt;Form.Control name=\"task\" \/&gt;\r\n        &lt;\/Form.Group&gt;\r\n        &lt;Form.Group&gt;\r\n          &lt;ButtonToolbar&gt;\r\n            &lt;Button appearance=\"primary\"&gt;Create&lt;\/Button&gt;\r\n          &lt;\/ButtonToolbar&gt;\r\n        &lt;\/Form.Group&gt;\r\n      &lt;\/Form&gt;\r\n    &lt;\/Panel&gt;\r\n  );\r\n};\r\n\r\nexport default TodoForm;<\/pre>\n<p><span style=\"font-weight: 400;\">\u1ede \u0111\u00e2y ch\u00fang ta import c\u00e1c components nh\u01b0 <\/span><a href=\"https:\/\/rsuitejs.com\/components\/flexbox-grid\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">FlexboxGrid<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/rsuitejs.com\/components\/panel\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Panel<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/rsuitejs.com\/components\/form\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Form<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/rsuitejs.com\/components\/button\/#button-toolbar\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">ButtonToolbar<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/rsuitejs.com\/components\/button\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Button<\/span><\/a><span style=\"font-weight: 400;\"> \u0111\u1ec3 t\u1ea1o form cho ng\u01b0\u1eddi d\u00f9ng nh\u1eadp todo. \u0110\u1ec3 s\u1eed d\u1ee5ng <\/span><b><i>TodoForm<\/i><\/b> <span style=\"font-weight: 400;\">component v\u1eeba \u0111\u01b0\u1ee3c t\u1ea1o, ch\u00fang ta c\u1ea7n import v\u00e0o file App.js:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">...\r\nimport TodoForm from \".\/components\/todos\/TodoForm\";\r\n...<\/pre>\n<p><span style=\"font-weight: 400;\">Sau \u0111\u00f3, th\u00eam <\/span><i><span style=\"font-weight: 400;\">TodoForm<\/span><\/i><span style=\"font-weight: 400;\"> v\u00e0o trong <\/span><i><span style=\"font-weight: 400;\">FlexboxGrid.Item<\/span><\/i><span style=\"font-weight: 400;\"> component. <\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">...\r\n&lt;FlexboxGrid.Item colspan={12}&gt;\r\n  &lt;TodoForm&gt;\r\n&lt;\/FlexboxGrid.Item&gt;\r\n...<\/pre>\n<p><span style=\"font-weight: 400;\">Khi b\u1ea1n quay l\u1ea1i browser, l\u1ea7n n\u00e0y b\u1ea1n s\u1ebd th\u1ea5y form nh\u1eadp todo.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193948\/6-300x197.png\" alt=\"6. Add ToDo\" width=\"300\" height=\"197\" class=\"size-medium wp-image-2971 aligncenter\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193948\/6-300x197.png 300w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193948\/6-1024x671.png 1024w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193948\/6-768x503.png 768w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193948\/6.png 1318w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<h3>T\u1ea1o Todo List<\/h3>\n<p><span style=\"font-weight: 400;\">B\u00e2y gi\u1edd, ch\u00fang ta s\u1ebd t\u1ea1o <\/span><i><span style=\"font-weight: 400;\">TodoList<\/span><\/i><span style=\"font-weight: 400;\"> component \u0111\u1ec3 hi\u1ec3n th\u1ecb danh s\u00e1ch Todo m\u00e0 ng\u01b0\u1eddi d\u00f9ng nh\u1eadp. T\u1ea1o file <\/span><b><i>TodoList.js<\/i><\/b> <span style=\"font-weight: 400;\">trong<\/span> <b><i>components<\/i><\/b> <span style=\"font-weight: 400;\">folder v\u00e0 th\u00eam \u0111o\u1ea1n code sau:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">import React from \"react\";\r\nimport { List, IconButton, FlexboxGrid } from \"rsuite\";\r\nimport { Icon } from \"@rsuite\/icons\";\r\n\r\nconst MinusSvg = React.forwardRef((props, ref) =&gt; (\r\n  &lt;svg {...props} xmlns=\"http:\/\/www.w3.org\/2000\/svg\" version=\"1.1\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" ref={ref}&gt;\r\n    &lt;title&gt;minus-copy&lt;\/title&gt;\r\n    &lt;path d=\"M2 7h12c0.552 0 1 0.448 1 1s-0.448 1-1 1h-12c-0.552 0-1-0.448-1-1s0.448-1 1-1z\" \/&gt;\r\n  &lt;\/svg&gt;\r\n));\r\n\r\nconst TodoList = () =&gt; {\r\n  const [todos, setTodos] = React.useState([]);\r\n\r\n  React.useEffect(() =&gt; {\r\n    fetch(\"http:\/\/jsonplaceholder.typicode.com\/posts?_limit=10\")\r\n      .then(res =&gt; res.json())\r\n      .then(posts =&gt; setTodos(posts))\r\n      .catch(err =&gt; {\r\n        console.error(err);\r\n      });\r\n  }, []);\r\n\r\n  return (\r\n    &lt;section&gt;\r\n      &lt;List&gt;\r\n        {todos.map((todo, i) =&gt; (\r\n          &lt;List.Item key={i} index={i}&gt;\r\n            &lt;FlexboxGrid justify=\"space-around\"&gt;\r\n              &lt;FlexboxGrid.Item colspan={12}&gt;\r\n                &lt;h5&gt;{todo.title}&lt;\/h5&gt;\r\n              &lt;\/FlexboxGrid.Item&gt;\r\n              &lt;FlexboxGrid.Item colspan={10}&gt;&lt;\/FlexboxGrid.Item&gt;\r\n              &lt;FlexboxGrid.Item colspan={2}&gt;\r\n                &lt;IconButton icon={&lt;Icon as={MinusSvg} \/&gt;} color=\"red\" appearance=\"primary\" circle \/&gt;\r\n              &lt;\/FlexboxGrid.Item&gt;\r\n            &lt;\/FlexboxGrid&gt;\r\n          &lt;\/List.Item&gt;\r\n        ))}\r\n      &lt;\/List&gt;\r\n    &lt;\/section&gt;\r\n  );\r\n};\r\n\r\n\r\nexport default TodoList;\r\n\r\n<\/pre>\n<p><span style=\"font-weight: 400;\">Trong \u0111o\u1ea1n code tr\u00ean, ch\u00fang ta import th\u00eam <\/span><a href=\"https:\/\/rsuitejs.com\/components\/list\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">List<\/span><\/a><span style=\"font-weight: 400;\"> v\u00e0 <\/span><a href=\"https:\/\/rsuitejs.com\/components\/button\/#icon-button\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">IconButton<\/span><\/a><span style=\"font-weight: 400;\"> t\u1eeb React Suite \u0111\u1ec3 \u0111\u1ecbnh ngh\u0129a cho danh s\u00e1ch todo trong application. Sau \u0111\u00f3 ch\u00fang ta s\u1ebd l\u1eb7p qua m\u1ea3ng c\u00e1c todos (\u1edf \u0111\u00e2y ch\u00fang m\u00ecnh fetch data m\u1eabu) v\u00e0 hi\u1ec3n th\u1ecb n\u1ed9i dung todo. Trong file <\/span><i><span style=\"font-weight: 400;\">App.js<\/span><\/i><span style=\"font-weight: 400;\">, import <\/span><i><span style=\"font-weight: 400;\">TodoList<\/span><\/i><span style=\"font-weight: 400;\"> component:<\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">...\r\nimport TodoList from \".\/components\/todos\/TodoList\";\r\n...<\/pre>\n<p><span style=\"font-weight: 400;\">Sau \u0111\u00f3 th\u00eam <\/span><i><span style=\"font-weight: 400;\">TodoList<\/span><\/i><span style=\"font-weight: 400;\"> v\u00e0o trong <\/span><i><span style=\"font-weight: 400;\">FlexboxGrid.Item<\/span><\/i><span style=\"font-weight: 400;\"> component. <\/span><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">...\r\n&lt;FlexboxGrid.Item colspan={12}&gt;\r\n  ...\r\n  &lt;TodoList \/&gt;\r\n&lt;\/FlexboxGrid.Item&gt;\r\n...<\/pre>\n<h3>Ch\u1ea1y application v\u00e0 xem l\u1ea1i giao di\u1ec7n ho\u00e0n ch\u1ec9nh<\/h3>\n<p><span style=\"font-weight: 400;\">\u1ee8ng d\u1ee5ng Todo App c\u1ee7a ch\u00fang ta hi\u1ec7n t\u1ea1i s\u1ebd tr\u00f4ng nh\u01b0 h\u00ecnh d\u01b0\u1edbi \u0111\u00e2y:<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193952\/7-300x196.png\" alt=\"7. Add ToDo Create\" width=\"300\" height=\"196\" class=\"size-medium wp-image-2972 aligncenter\" srcset=\"https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193952\/7-300x196.png 300w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193952\/7-1024x670.png 1024w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193952\/7-768x503.png 768w, https:\/\/mevn-public.s3-ap-southeast-1.amazonaws.com\/marketenterprise.vn\/wp-images\/2023\/01\/30193952\/7.png 1318w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Nh\u01b0 v\u1eady l\u00e0 v\u1edbi s\u1ef1 tr\u1ee3 gi\u00fap c\u1ee7a th\u01b0 vi\u1ec7n RSuite, ch\u1ec9 c\u1ea7n m\u1ed9t \u00edt th\u1eddi gian l\u00e0 ch\u00fang ta \u0111\u00e3 c\u00f3 th\u1ec3 x\u00e2y d\u1ef1ng \u0111\u01b0\u1ee3c m\u1ed9t UI tr\u00f4ng kh\u00e1 \u0111\u1eb9p d\u00e0nh cho Todo App. B\u1ea1n c\u00f3 th\u1ec3 b\u1ed5 sung th\u00eam ph\u1ea7n thao t\u00e1c v\u1edbi d\u1eef li\u1ec7u (CRUD) \u0111\u1ec3 t\u1ea1o n\u00ean Todo App ho\u00e0n ch\u1ec9nh. \u1ede b\u00e0i vi\u1ebft n\u00e0y, ch\u00fang m\u00ecnh ch\u1ec9 gi\u1edbi thi\u1ec7u c\u00e1ch d\u00f9ng components c\u1ee7a React Suite \u0111\u1ec3 x\u00e2y d\u1ef1ng giao di\u1ec7n cho application.<\/span><\/p>\n<h2>K\u1ebft lu\u1eadn<\/h2>\n<p><span style=\"font-weight: 400;\">K\u1ebft th\u00fac b\u00e0i vi\u1ebft n\u00e0y, b\u1ea1n \u0111\u00e3 \u0111\u01b0\u1ee3c l\u00e0m quen v\u1edbi th\u01b0 vi\u1ec7n UI cho React l\u00e0 RSuite. Ch\u00fang ta c\u0169ng \u0111\u00e3 c\u00f3 th\u1ec3 t\u1ea1o giao di\u1ec7n Todo App m\u1ed9t c\u00e1ch d\u1ec5 d\u00e0ng b\u1eb1ng c\u00e1ch import v\u00e0 s\u1eed d\u1ee5ng c\u00e1c component m\u00e0 RSuite cung c\u1ea5p s\u1eb5n.<\/span><span style=\"font-weight: 400;\"> M\u00ecnh tin r\u1eb1ng m\u1ed7i l\u1ea7n th\u1ef1c h\u00e0nh s\u1ebd t\u1ea1o ra nhi\u1ec1u s\u1ef1 kh\u00e1c bi\u1ec7t, v\u00ec v\u1eady n\u1ebfu c\u00e1c b\u1ea1n c\u00f3 h\u1ee9ng th\u00fa v\u1edbi vi\u1ec7c x\u00e2y d\u1ef1ng m\u1ed9t giao di\u1ec7n t\u01b0\u01a1ng t\u00e1c v\u1edbi user m\u1ed9t c\u00e1ch d\u1ec5 d\u00e0ng, h\u00e3y b\u1eaft tay v\u00e0o t\u00ecm hi\u1ec3u, s\u1eed d\u1ee5ng React Suite v\u00e0 m\u1edf r\u1ed9ng th\u00eam c\u00e1c ch\u1ee9c n\u0103ng c\u1ee7a application.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">C\u00f3 m\u1ed9t l\u01b0u \u00fd l\u00e0 React Suite \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf v\u00e0 tri\u1ec3n khai \u0111\u1ec3 s\u1eed d\u1ee5ng tr\u00ean desktop browsers thay v\u00ec mobile browsers, v\u00ec v\u1eady n\u1ebfu c\u00e1c b\u1ea1n mu\u1ed1n ph\u00e1t tri\u1ec3n s\u1ea3n ph\u1ea9m c\u00f3 th\u1ec3 responsive tr\u00ean mobile browsers th\u00ec c\u1ea7n c\u00e2n nh\u1eafc n\u00ean s\u1eed d\u1ee5ng UI Framework kh\u00e1c ph\u00f9 h\u1ee3p h\u01a1n.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">M\u00ecnh mong l\u00e0 b\u00e0i vi\u1ebft s\u1ebd mang l\u1ea1i h\u1eefu \u00edch cho nh\u1eefng b\u1ea1n \u0111ang t\u00ecm hi\u1ec3u v\u1ec1 UI Framework. Ch\u00fac c\u00e1c b\u1ea1n c\u00f3 m\u1ed9t ng\u00e0y t\u1ed1t l\u00e0nh \ud83d\ude00<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Trong b\u00e0i vi\u1ebft n\u00e0y, ch\u00fang ta s\u1ebd c\u00f9ng nhau t\u00ecm hi\u1ec3u v\u1ec1 UI Framework RSuite JS. Nh\u01b0ng tr\u01b0\u1edbc ti\u00ean h\u00e3y c\u00f9ng t\u00ecm hi\u1ec3u v\u1ec1 Framework RSuite JS.<\/p>\n","protected":false},"author":44,"featured_media":2966,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[132,134,129,128,131,22,130,133],"class_list":["post-2964","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology","tag-application","tag-framework","tag-javascript","tag-react","tag-rsuite","tag-technical","tag-todo-app","tag-ui"],"_links":{"self":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts\/2964","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/comments?post=2964"}],"version-history":[{"count":0,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/posts\/2964\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/media\/2966"}],"wp:attachment":[{"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/media?parent=2964"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/categories?post=2964"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.marketenterprise.vn\/blog\/wp-json\/wp\/v2\/tags?post=2964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}