{"id":2000,"date":"2022-03-25T08:35:49","date_gmt":"2022-03-25T08:35:49","guid":{"rendered":"https:\/\/migoda.vn\/xay-dung-website-voi-reactjs-1648197341"},"modified":"2023-04-23T04:19:48","modified_gmt":"2023-04-23T04:19:48","slug":"xay-dung-website-voi-reactjs-1648197341","status":"publish","type":"post","link":"https:\/\/migoda.vn\/blog\/xay-dung-website-voi-reactjs-1648197341\/","title":{"rendered":"H\u01b0\u1edbng d\u1eabn x\u00e2y d\u1ef1ng web app v\u1edbi reactjs m\u1edbi nh\u1ea5t 2020 – X\u00e2y d\u1ef1ng web"},"content":{"rendered":"
\n
\n

B\u1ea1n \u0111ang \u0111\u1ecdc: H\u01b0\u1edbng d\u1eabn x\u00e2y d\u1ef1ng web app v\u1edbi reactjs m\u1edbi nh\u1ea5t 2020 – X\u00e2y d\u1ef1ng web<\/a><\/span><\/p>\n<\/div>\n

Rate this post<\/span><\/p>\n

X\u00e2y d\u1ef1ng web app v\u1edbi reactjs<\/strong> l\u00e0 m\u1ed9t trong nh\u1eefng keyword \u0111\u01b0\u1ee3c search nhi\u1ec1u nh\u1ea5t tr\u00ean Google v\u1ec1 ch\u1ee7 \u0111\u1ec1 x\u00e2y d\u1ef1ng web app v\u1edbi reactjs<\/strong>. Trong b\u00e0i vi\u1ebft n\u00e0y, xaydungweb.vn s\u1ebd vi\u1ebft b\u00e0i vi\u1ebft H\u01b0\u1edbng d\u1eabn x\u00e2y d\u1ef1ng web app v\u1edbi reactjs m\u1edbi nh\u1ea5t 2020.<\/span><\/p>\n

\"X\u00e2y<\/span><\/p>\n

H\u01b0\u1edbng d\u1eabn x\u00e2y d\u1ef1ng web app v\u1edbi reactjs m\u1edbi nh\u1ea5t 2020<\/span><\/h2>\n

di\u1ec5n \u0111\u1ea1t<\/span><\/h3>\n

v\u1eadn d\u1ee5ng n\u00e0y l\u00e0 m\u1ed9t website app thu\u1eadn ti\u1ec7n c\u00f3 t\u00ednh n\u0103ng chat realtime gi\u1eefa nh\u1eefng ng\u01b0\u1eddi d\u00f9ng, ph\u1ea7n frontend s\u1ebd \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng b\u1eb1ng ReactJs v\u00e0 \u0111\u00e2y c\u0169ng ch\u00ednh l\u00e0 tr\u1ecdng t\u00e2m ki\u1ebfn th\u1ee9c v\u00e0 k\u1ef9 n\u0103ng m\u00e0 m\u00ecnh mu\u1ed1n san s\u1ebb v\u1edbi nh\u1eefng b\u1ea1n. C\u00f2n backend s\u1ebd l\u00e0 m\u1ed9t server node.js l\u00e0m ngh\u0129a v\u1ee5 v\u00e0 tr\u00e1ch nhi\u1ec7m send v\u00e0 nh\u1eadn tin nh\u1eafn gi\u1eefa nh\u1eefng user, hi\u1ec3n nhi\u00ean l\u00e0 s\u1ebd realtime ngh\u0129a l\u00e0 b\u1ea1n kh\u00f4ng c\u1ea7n ph\u1ea3i reload l\u1ea1i trang m\u00e0 lu\u00f4n lu\u00f4n \u0111\u1ee7 n\u1ed9i l\u1ef1c nh\u1eadn \u0111\u01b0\u1ee3c tin nh\u1eafn t\u1eeb ng\u01b0\u1eddi d\u00f9ng kh\u00f4ng gi\u1ed1ng send \u0111\u1ebfn cho m\u00ecnh, v\u00e0 th\u01b0 vi\u1ec7n socket.io s\u1ebd gi\u00fap ta s\u1eed d\u1ee5ng vi\u1ec7c \u0111\u00f3. N\u1ebfu b\u1ea1n ch\u01b0a bi\u1ebft v\u1ec1 node.js v\u00e0 socket.io th\u00ec c\u0169ng k y\u1ebfu t\u1ed1 g\u00ec, khi c\u1ea7n d\u00f9ng m\u00ecnh s\u1ebd di\u1ec5n \u0111\u1ea1t v\u1ec1 n\u00f3, v\u00e0 v\u00ec node.js v\u00e0 socket.io \u0111\u1ec1u \u0111\u01b0\u1ee3c vi\u1ebft b\u1eb1ng javascript n\u00ean t\u1ea5t c\u1ea3 ch\u00fang ta s\u1ebd gi\u00fap quen v\u1edbi n\u00f3 r\u1ea5t mau .<\/span><\/p>\n

chu\u1ea9n b\u1ecb s\u1eb5n s\u00e0ng\u00a0k\u1ef9 n\u0103ng v\u00e0 ki\u1ebfn th\u1ee9c<\/span><\/h3>\n

\u0110\u1ec3 l\u00e0m \u0111\u01b0\u1ee3c v\u1eadn d\u1ee5ng n\u00e0y th\u00ec b\u1ea1n ph\u1ea3i c\u00f3 hi\u1ec3u bi\u1ebft c\u01a1 b\u1ea3n v\u1ec1 ReactJs r\u1ed3i, hi\u1ec3u v\u1ec1 m\u1ed9t s\u1ed1 \u00edt \u0111\u1ecbnh ngh\u0129a nh\u01b0 components, props, state, handling events, lifecycle \u2026 V\u00e0 c\u0169ng c\u1ea7n hi\u1ec3u bi\u1ebft m\u1ed9t t\u00ed v\u1ec1 ES6. Nh\u01b0ng n\u1ebfu nh\u1eefng b\u1ea1n ch\u01b0a bi\u1ebft th\u00ec c\u0169ng kh\u00f4ng sao, trong l\u00fac s\u1eed d\u1ee5ng m\u00ecnh s\u1ebd l\u00fd gi\u1ea3i t\u1eebng \u0111o\u1ea1n code, n\u1ebfu \u0111\u1ecdc code m\u00e0 nh\u1eefng b\u1ea1n v\u1eabn kh\u00f4ng hi\u1ec3u th\u00ec c\u0169ng kh\u00f4ng sao, c\u1ee9 sao ch\u00e9p code cho ch\u1ea1y \u0111\u01b0\u1ee3c r\u1ed3i hi\u1ec3u sau ( m\u00ecnh c\u0169ng hay gi\u1ed1ng nh\u01b0 th\u1ebf ). \u0110i\u1ec1u quan tr\u1ecdng l\u00e0 b\u1ea1n mong \u01b0\u1edbc l\u00e0m ra \u1ee9ng d\u1ee5ng n\u00e0y m\u00e0 th\u00f4i. Nh\u01b0ng m\u00ecnh v\u1eabn khuy\u1ebfn kh\u00edch nh\u1eefng b\u1ea1n nghi\u00ean c\u1ee9u v\u00e0 \u0111i\u1ec1u tra v\u1ec1 react tr\u01b0\u1edbc v\u00ec khi \u0111\u00f3 b\u1ea1n s\u1ebd thu\u1eadn ti\u1ec7n theo d\u00f5i b\u00e0i vi\u1ebft n\u00e0y h\u01a1n. ebook v\u1ec1 ReacJS c\u00f3 r\u1ea5t nhi\u1ec1u tr\u00ean m\u1ea1ng, b\u1ea1n ho\u00e0n to\u00e0n c\u00f3 th\u1ec3 \u0111\u1ecdc qua m\u1ed9t s\u1ed1 \u00edt project thu\u1eadn ti\u1ec7n g\u1ee3i \u00fd https:\/\/github.com\/DoanhPHAM\/todo, v\u00e0 \u0111\u1ecdc document https:\/\/reactjs.org\/docs\/hello-world.html<\/span><\/p>\n

thi\u1ebft l\u1eadp\u00a0giao di\u1ec7n cho\u00a0v\u1eadn d\u1ee5ng\u00a0b\u1eb1ng React<\/span><\/h3>\n

ti\u00ean phong, tr\u01b0\u1edbc khi x\u00e2y d\u1ef1ng giao di\u1ec7n b\u1eb1ng React th\u00ec c\u1ea7n ph\u1ea3i bi\u1ebft giao di\u1ec7n n\u00f3 th\u1ebf n\u00e0o, l\u00ean google search \u2018 bootstrap chat template \u2019 r\u1ed3i long dong m\u1ed9t s\u1ed1 \u00edt trang, m\u00ecnh c\u0169ng ch\u1ecdn \u0111\u01b0\u1ee3c c\u00e1i giao di\u1ec7n h\u00e0i l\u00f2ng, v\u00e0 n\u00f3 \u0111\u00e2y https:\/\/bootsnipp.com\/snippets\/WaEvr<\/span><\/p>\n

Kh\u1edfi t\u1ea1o\u00a0v\u1eadn d\u1ee5ng\u00a0React<\/span><\/h3>\n

Khi\u00a0\u0111\u00e3\u00a0c\u00f3 giao di\u1ec7n html thu\u1ea7n r\u1ed3i th\u00ec ta ph\u1ea3i chuy\u1ec3n n\u00f3 qua React, v\u00e0 \u0111\u00e2y c\u0169ng ch\u00ednh l\u00e0 ph\u1ea7n kh\u00f3 nh\u1ea5t trong\u00a0post\u00a0n\u00e0y. \u0110\u1ec3 chuy\u1ec3n giao di\u1ec7n qua React \u0111i\u1ec1u\u00a0tr\u01b0\u1edbc ti\u00ean\u00a0l\u00e0 c\u00e1c b\u1ea1n ph\u1ea3i kh\u1edfi t\u1ea1o project React, \u0111\u1ec3 c\u00f3 m\u1ed9t project React t\u1ed1t nh\u1ea5t, ta c\u1ea7n ph\u1ea3i bi\u1ebft \u0111\u1ebfn npm, babel, webpack.\u00a0\u0111\u1ed1i v\u1edbi\u00a0ng\u01b0\u1eddi m\u1edbi th\u00ec vi\u1ec7c config s\u1ebd kh\u00e1\u00a0ph\u1ee9c t\u1ea1p, nh\u01b0ng\u00a0k\u00a0sao \u0111\u1ec3\u00a0kh\u00f4ng kh\u00f3 kh\u0103n, ch\u00fang ta s\u1ebd\u00a0kh\u00f4ng\u00a0kh\u1edfi t\u1ea1o project b\u1eb1ng tay m\u00e0 b\u1eb1ng\u00a0Create React App<\/code>, n\u00f3 l\u00e0 m\u1ed9t package gi\u00fap\u00a0t\u1ef1 \u0111\u1ed9ng h\u00f3a\u00a0vi\u1ec7c\u00a0x\u00e2y d\u1ef1ng\u00a0\u1ee9ng d\u1ee5ng\u00a0React. \u0110\u1ec3\u00a0c\u00e0i \u0111\u1eb7t\u00a0\u0111\u01b0\u1ee3c package\u00a0Create React App<\/code>\u00a0m\u00e1y t\u00ecnh c\u1ea7n \u0111\u01b0\u1ee3c\u00a0c\u00e0i \u0111\u1eb7t\u00a0Node.Js, m\u00ecnh s\u1ebd m\u1eb7c \u0111\u1ecbnh c\u00e1c b\u1ea1n\u00a0v\u1eeba m\u1edbi\u00a0c\u00e0i Node js r\u1ed3i, n\u1ebfu ch\u01b0a th\u00ec c\u00e1c b\u1ea1n google \u0111\u1ec3 c\u00e0i nha, c\u1ee9 b\u1ea3n m\u1edbi nh\u1ea5t m\u00e0 c\u00e0i th\u00f4i\u00a0x\u00e2y d\u1ef1ng\u00a0command line l\u00ean v\u00e0 g\u00f5<\/span><\/p>\n

npm install -g create-react-app<\/code><\/span><\/pre>\n

Create React App<\/code>\u00a0s\u1ebd \u0111\u01b0\u1ee3c\u00a0c\u00e0i \u0111\u1eb7t\u00a0c\u1ee5c b\u1ed9 tr\u00ean m\u00e1y t\u00ednh,\u00a0k\u1ebf ti\u1ebfp\u00a0kh\u1edfi t\u1ea1o\u00a0\u00e1p d\u1ee5ng<\/span><\/p>\n

create-react-app chat-client<\/code><\/span><\/pre>\n

v\u1edbi chat-client l\u00e0 t\u00ean c\u1ee7a project sau khi c\u00e0i xong, c\u00e1c b\u1ea1n\u00a0cd chat-client<\/code>\u00a0v\u00e0 ch\u1ea1y l\u1ec7nh<\/span><\/p>\n

npm run<\/code><\/span><\/pre>\n

n\u1ebfu tr\u00ecnh duy\u1ec7t b\u1eadt l\u00ean tab th\u1ebf n\u00e0y l\u00e0 ch\u00fang ta\u00a0v\u1eeba m\u1edbi\u00a0kh\u1edfi t\u1ea1o\u00a0th\u00e0nh c\u00f4ng\u00a0project React\"\"Sau khi ch\u1ea1y xong, b\u1ea1n\u00a0\u0111ang\u00a0c\u00f3\u00a0\u1ee9ng d\u1ee5ng\u00a0chat-client, c\u1ea5u tr\u00fac th\u01b0 m\u1ee5c c\u1ee7a\u00a0\u1ee9ng d\u1ee5ng\u00a0gi\u1ed1ng nh\u01b0\u00a0sau:<\/span><\/p>\n

\u251c\u2500\u2500 README.md\r\n\u251c\u2500\u2500 node_modules\r\n\u251c\u2500\u2500 package.json\r\n\u251c\u2500\u2500 .gitignore\r\n\u251c\u2500\u2500 public\r\n\u2502   \u2514\u2500\u2500 favicon.ico\r\n\u2502   \u2514\u2500\u2500 index.html\r\n\u2502   \u2514\u2500\u2500 manifest.json\r\n\u2514\u2500\u2500 src\r\n    \u2514\u2500\u2500 App.css\r\n    \u2514\u2500\u2500 App.js\r\n    \u2514\u2500\u2500 App.test.js\r\n    \u2514\u2500\u2500 index.css\r\n    \u2514\u2500\u2500 index.js\r\n    \u2514\u2500\u2500 logo.svg\r\n    \u2514\u2500\u2500 registerServiceWorker.js<\/code><\/span><\/pre>\n

cu\u1ed1i c\u00f9ng b\u1ea1n\u00a0m\u1edf\u00a0file\u00a0package.json<\/code>\u00a0l\u00ean v\u00e0\u00a0thay \u0111\u1ed5i\u00a0n\u1ed9i dung\u00a0th\u00e0nh\u00a0nh\u01b0\u00a0n\u00e0y<\/span><\/p>\n

\r\n\"name\": \"client\",\r\n\"version\": \"0.1.0\",\r\n\"private\": true,\r\n\"homepage\": \"https:\/\/ththth0303.github.io\/chat-client\",\r\n\"author\": \"Thang\",\r\n\"dependencies\": \" gh-pages \" : \" ^ 1.0.0 \", \" jquery \" : \" ^ 3.2.1 \", \" lodash \" : \" ^ 4.17.4 \", \" react \" : \" ^ 16.0.0 \", \" react-dom \" : \" ^ 16.0.0 \", \" react-scripts \" : \" 1.0.14 \", \" socket.io - client \" : \" ^ 2.0.4 \",\r\n\"scripts\": \" start \" : \" react-scripts start \", \" build \" : \" react-scripts build \", \" test \" : \" react-scripts tra c\u1ee9u -- env = jsdom \", \" eject \" : \" react-scripts eject \", \" deploy \" : \" react-scripts build v\u00e0 v\u00e0 gh-pages - d build \"\r\n<\/code><\/span><\/pre>\n

\u0111\u1ec3 \u00fd\u00a0tr\u01b0\u1eddng\u00a0homepage<\/code>\u00a0b\u1ea1n c\u1ea7n\u00a0thay \u0111\u1ed5i\u00a0chat-client<\/code>\u00a0b\u1eb1ng t\u00ean reopsitory github c\u1ee7a b\u1ea1n \u0111\u1ec3\u00a0gi\u00fap s\u1ee9c\u00a0cho vi\u1ec7c deploy sau n\u00e0y.\u00a0ti\u1ebfp theo,\u00a0setup\u00a0c\u00e1c g\u00f3i\u00a0quan tr\u1ecdng, ch\u1ea1y<\/span><\/p>\n

npm install<\/code><\/span><\/pre>\n

Chia components<\/span><\/h3>\n

\u0110\u00e2y l\u00e0 giao di\u1ec7n chat m\u00e0 m\u00ecnh gi\u1edbi th\u1ec7u v\u1edbi c\u00e1c b\u1ea1n, nh\u1eefng khung m\u00e0u\u00a0kh\u00e1c\u00a0nhau l\u00e0 nh\u1eefng components m\u00e0 m\u00ecnh chia, vi\u1ec7c chia components n\u00e0y ch\u01b0a h\u1eb3n l\u00e0\u00a0t\u0103ng cao\u00a0v\u00ec n\u00f3\u00a0v\u1eabn\u00a0\u0111\u1ee7 n\u1ed9i l\u1ef1c\u00a0chia nh\u1ecf\u00a0th\u00eam n\u1eefa\u00a0\u0111\u1ec3\u00a0easy\u00a0cai qu\u1ea3n, nh\u01b0ng\u00a0\u0111\u1ed1i v\u1edbi\u00a0ng\u01b0\u1eddi m\u1edbi ch\u01b0a quen v\u1edbi vi\u1ec7c\u00a0l\u00e0m\u00a0vi\u1ec7c v\u1edbi c\u00e1c components th\u00ec s\u1ebd kh\u00e1 l\u00e0\u00a0m\u1edb b\u00f2ng bong, n\u00ean m\u00ecnh ch\u1ec9 chia\u00a0\u0111\u01a1n gi\u1ea3n\u00a0v\u1eady th\u00f4i\u00a0\"\"\u00a0Ngo\u00e0i c\u00f9ng l\u00e0 component App, c\u00e1c b\u1ea1n v\u00e0o trong th\u01b0 m\u1ee5c\u00a0src<\/code>, \u0111\u00e2y l\u00e0 th\u01b0 m\u1ee5c\u00a0l\u00e0m\u00a0vi\u1ec7c ch\u00ednh ch\u1ee9a sourec code c\u1ee7a c\u00e1c b\u1ea1n,\u00a0m\u1edf\u00a0file\u00a0App.js<\/code>\u00a0ra, x\u00f3a c\u00e1i code c\u0169 \u0111i v\u00e0\u00a0copy\u00a0\u0111\u00e8 \u0111o\u1ea1n code n\u00e0y l\u00ean, c\u00e1c\u00a0b\u1ea1n \u0111\u1ecdc\u00a0comment\u00a0b\u00ean trong code \u0111\u1ec3 hi\u1ec3u h\u01a1n nh\u00e9<\/span><\/p>\n

import React from 'react';\r\nimport $ from 'jquery';\r\nimport Messages from '.\/message-list';\r\nimport Input from '.\/input';\r\nimport _map from 'lodash\/map';\r\nimport io from 'socket.io-client';\r\n\r\nimport '.\/App.css';\r\n\r\nexport default class App extends React.Component constructor ( props ) super ( props ) ; \/ \/ Kh\u1edfi t\u1ea1o state, this.state = messages : [ id : 1, userId : 0, message : ' Hello ' ], user : null, this.socket = null ; \/ \/ Connetct v\u1edbi server nodejs, tr\u1ea3i qua socket.io componentWillMount ( ) this.socket = io ( ' localhost : 6969 ' ) ; this.socket.on ( ' id ', res => this. setState ( user : res ) ) \/ \/ l\u1eafng nghe s\u1ef1 ki\u1ec7n c\u00f3 t\u00ean ' id ' this.socket.on ( ' newMessage ', ( response ) => this. newMessage ( response ) ) ; \/ \/ l\u1eafng nghe s\u1ef1 ki\u1ec7n ' newMessage ' v\u00e0 g\u1ecdi h\u00e0m newMessage khi c\u00f3 s\u1ef1 ki\u1ec7n \/ \/ Khi c\u00f3 inbox m\u1edbi, s\u1ebd push tin nh\u1eafn v\u00e0o state mesgages, v\u00e0 n\u00f3 s\u1ebd \u0111\u01b0\u1ee3c render ra m\u00e0n h\u00ecnh hi\u1ec3n th\u1ecb newMessage ( m ) const messages = this.state.messages ; let ids = _map ( messages, ' id ' ) ; let max = Math. max ( ... ids ) ; messages.push ( id : max + 1, userId : m.id, message : m.data ) ; let objMessage = $ ( '. messages ' ) ; if ( objMessage [ 0 ]. scrollHeight - objMessage [ 0 ]. scrollTop = = = objMessage [ 0 ]. clientHeight ) this. setState ( messages ) ; objMessage. animate ( scrollTop : objMessage. prop ( ' scrollHeight ' ), 300 ) ; \/ \/ t\u1ea1o hi\u1ec7u \u1ee9ng cu\u1ed9n khi c\u00f3 inbox m\u1edbi else this. setState ( messages ) ; if ( m.id = = = this.state.user ) objMessage. animate ( scrollTop : objMessage. prop ( ' scrollHeight ' ), 300 ) ; \/ \/ G\u1eedi s\u1ef1 ki\u1ec7n socket newMessage v\u1edbi t\u00e0i li\u1ec7u l\u00e0 n\u1ed9i dung tin nh\u1eafn sendnewMessage ( m ) if ( m.value ) this.socket.emit ( \" newMessage \", m.value ) ; \/ \/ g\u1eedi s\u1ef1 ki\u1ec7n v\u1ec1 server m.value = \" \" ; render ( ) return (<\/code><\/span><\/pre>\n

chat box<\/code><\/span><\/h3>\n

this.state.user messages = this.state.messages typing = this.state.typing\/ > this. sendnewMessage. bind ( this ) \/ ><\/code><\/span><\/p>\n

)<\/code><\/span><\/p>\n

ti\u1ebfp theo\u00a0l\u00e0 component khoanh m\u00e0u \u0111\u1ecf, component\u00a0Input<\/code>, t\u1ea1o file\u00a0input.js<\/code><\/span><\/p>\n

import React from 'react';\r\n\r\nexport default class App extends React.Component checkEnter ( e ) console.log ( e ) if ( e. keyCode = = = 13 ) this.props. sendMessage ( this.refs. messageInput ) ; render ( ) return (<\/code><\/span><\/pre>\n

this. checkEnter. bind ( this ) \/ ><\/code><\/span><\/p>\n

() => this.props.sendMessage(this.refs.messageInput) ref=\"inputMessage\" ><\/code><\/span><\/p>\n

\n

Xem th\u00eam: Quy tr\u00ecnh thi\u1ebft k\u1ebf website \u2013 C\u00e1c b\u01b0\u1edbc thi\u1ebft k\u1ebf website chuy\u00ean nghi\u1ec7p<\/a><\/span><\/p>\n<\/div>\n

<\/code><\/span><\/p>\n

Send<\/code><\/span><\/p>\n

<\/code><\/span><\/p>\n

)<\/code><\/span><\/p>\n

Component m\u00e0u t\u00edm l\u00e0 component MessageItem, t\u1ea1o file\u00a0message-item.js<\/code><\/span><\/p>\n

import React from 'react';\r\n\r\nimport '.\/item.scss';\r\n\r\nexport default class App extends React.Component render ( ) return (<\/code><\/span><\/pre>\n