Reactjs - Bài 5 - state là gì
Goal
Giới thiệu vềstate
trong React và cách sử dụng nó.Giới thiệu
Hãy chạy lại fileprops
trong ví dụ trước:https://slack-files.com/T035VUSF2-F060CUFL1-939dd508dd
Mở Google Chrome Dev Tool, và in ra các giá trị như sau:
(Click vào để mở lớn)
Ta có thể thấy,
props
đóng vai trò như là IF để truyền data từ parent vào trong Component, nó được “sở hữu” bởi parent đó. Có thể coi props
như một Component’s configuration. Còn
state
như là một biến private của Component. Chúng ta có thể change states
bằng cách gọi this.setState()
Lưu ý: trong bài trước, để thay đổi
props
ta phải gọi setProps
từ bên ngoài Component: AvatarComponent.setProps
Ví dụ để hiểu rõ hơn state
:
Ta sẽ lấy ví dụ trước và thử đưa state
vào trong Component Avatar. Bởi vì state
dùng cho việc thay đổi nội bộ trong Component, cho nên ta hãy xem cái gì trong nội bộ Avatar Component có thể thay đổi được một cách nội bộ.OK, ta thử thay đổi image của avatar. Ý tưởng như sau: khi click vào button, thì image của avatar thay đổi.
Source code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Basic Example Props</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script type="text/jsx">
var Avatar = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired
},
getInitialState() {
return {
src: 'http://canime.files.wordpress.com/2010/05/mask-dtb.jpg'
};
},
onClick() {
this.setState({src: 'http://38.media.tumblr.com/9f96b52d8fda03c77d0b620d4f12a128/tumblr_n0lvu7fSqE1sont7fo1_500.gif'});
},
render() {
//var src='http://canime.files.wordpress.com/2010/05/mask-dtb.jpg';
return (
<div>
<img src={this.state.src} width={this.props.width} height={this.props.height} alt="alt" />
<span>{this.props.name}</span>
<button onClick={this.onClick}>So HOT!!!!</button>
</div>
);
}
});
var AvatarEl = <Avatar name="Foo" width={100} height={100}/>;
var AvatarComponent = React.render(AvatarEl, document.body);
</script>
</body>
</html>
Hãy thử chạy file source trên, click vào button, bạn có thấy image của avatar đã thay đổi!Về cơ bản cấu trúc một Component có
state
như sau:- method render()
- method getIntialState(): initial giá trị
state
cho Component. Trong ví dụ trên, chúng ta initial giá trịsrc
củastate
làhttp://canime.files.wordpress.com/2010/05/mask-dtb.jpg
- method handle Event: đây là method dùng để handle sự kiện trong Component. Hay cũng chính là callback function của event. Trong ví dụ trên, khi có sự kiện
click
thì nó thực thi methodonClick()
thay đổi image source của avatar. - this.setState: được gọi trong method
onClick
, sẽ thay đổi data trong Component -> trigger render -> rerender View của Component.
Sự giống nhau props
và state
- props và state đều là plain JS objects
- props và state đều trigger render update khi thay đổi
Sự khác nhau props
và state
Features | props | state |
---|---|---|
Can get initial value from parent Component? | Yes | Yes |
Can be changed by parent Component? | Yes | No |
Can set default values inside Component?* | Yes | Yes |
Can change inside Component? | No | Yes |
Can set initial value for child Components? | Yes | Yes |
Can change in child Components? | Yes | No |
Reactjs - Bài 4 - props là gì
Goal
Giới thiệu props và làm sao sử dụng nó.Giới thiệu
Trong bài trước, chúng ta đã có dịp tiếp xúc vớiprops
, khi dùng nó để truyền giá trị name
là ‘Phúng’ vào trong.Vậy
props
là gì? Nó đóng vai trò như thế nào trong React Component?
props
là gì
props
là một attribute của Component. Chúng ta có thể sử dụng props
như là một Object hay là một Function
props
đóng vai trò gì
props
chứa giá trị được chuyển từ bên ngoài vào trong Component.PropTypes
Khi bạn muốn validateprops
, hãy sử dụng PropTypes
để làm việc đó.var Avatar = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
id: React.PropTypes.number.isRequired,
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
alt: React.PropTypes.string
},
render() {
var src = `/img/avatar/${this.props.id}.png`;
return (
<div>
<img src={src} width={this.props.width} height={this.props.height} alt={this.props.alt} />
<span>{this.props.name}</span>
</div>
);
}
});
<Avatar name="foo" width={100} height={100} />
Default Prop value
React cung cấp cho bạn cách define default valuse choprops
rất rõ ràng var Hello = React.createClass({
getDefaultProps() {
return {
name: "React"
};
},
render() {
return <div>Hello {this.props.name}</div>
}
});
setProps và replaceProps
Khi bạn gọisetProps()
, nó sẽ thay đổi properties của Component và trigger một re-render. Ngoài ra, bạn cũng có thể đưa vào một callback function mà sẽ được thực thi một khi setProps
được hoàn thành. Hãy thử chạy ví dụ sau
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Basic Example Props</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script type="text/jsx">
var Avatar = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired
},
render() {
var src='http://canime.files.wordpress.com/2010/05/mask-dtb.jpg';
return (
<div>
<img src={src} width={this.props.width} height={this.props.height} alt="alt" />
<span>{this.props.name}</span>
</div>
);
}
});
var AvatarEl = <Avatar name="Foo" width={100} height={100}/>;
var AvatarComponent = React.render(AvatarEl, document.body);
</script>
</body>
</html>
Bây giờ, ta thử thay đổi các properties name của AvatarComponent ở trên bằng cách thêm đoạn code sau: AvatarComponent.setProps({name: "Bar"}, function(){
alert("AvatarComponent setProps Done!");
});
Sau đó, bạn thử refresh lại trang tên của Avatar giờ thành ‘Bar’, và sau khi setProps()
hoàn thành thì nó thực thì callback function là alert string “AvatarComponent setProps Done!”. Bây giờ, ta thử dùng
replaceProps()
để thay đổi properties name của AvatarComponent ở trên bằng cách thêm đoạn code sau: AvatarComponent.replaceProps({name: "Bar-Foo"}, function(){
alert("AvatarComponent replaceProps Done!");
});
Bạn có thấy điều gì khác giữa setProps()
và replaceProps()
không? Với
setProps()
nó merge property nào mà nó set.Với
replaceProps()
nó delete các props tồn tại trước đó và thay bởi properties mới.
Reactjs - Bài 3 - JSX là gì
GOAL
Giới thiệu về JSX.JSX là gì
JSX = Javascript + XML
.Thử một ví dụ JSX đơn giản
Hãy quay trở lại ví dụ trong bài giới thiệu ‘Hello World’, phần 1. <script>
var helloEl = React.createElement('div', { className: 'hello' }, 'Hello, world!');
React.render(
helloEl,
document.body
);
</script>
Bây giờ ta thử viết lại theo syntax JSX <script type="text/jsx">
var helloEl = <div className: "hello">Hello, world!</div>;
React.render(
helloEl,
document.body
);
</script>
Bây giờ bạn thử chạy source code sau:<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Basic Example Hello world</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script type="text/jsx">
var helloEl = <div className="hello">Hello, World!</div>
React.render(
helloEl,
document.body
);
</script>
</body>
</html>
Có phải là nó cũng hiển thị ra trang HTML giống như ví dụ trước không? Đó là nhờ vào React JSX. React JSX sẽ transform XML-like syntax thành Javascript. Các XML elements, attributes và children được chuyển đổi thành các đối số truyền vào React.createElement.//Input (JSX)
var helloEl = <div className: "hello">Hello, world!</div>;
//Output (JS)
var helloEl = React.createElement('div', { className: 'hello' }, 'Hello, world!');
HTML Tags vs. React Components
React có thể render HTML tags (dạng string) hay React components.Để render một HTML tag, chỉ cần sử dụng tên bằng chữ viết thường trong JSX.
ở trên là một ví dụ.
Để render một React Component, chỉ cần tạo một biến local bắt đầu bằng chữ cái viết Hoa. Ví dụ:
var Nav;
// Input (JSX)
var app = <Nav color="blue" />;
// Output (JS)
var app = React.createElement(Nav, {color:"blue"});
JSX cũng cho phép chỉ định children sử dụng XML syntax:var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
Nav,
{color:"blue"},
React.createElement(Profile, null, "click")
);
Về JSX còn có những phần thú vị khác như Namespaced Components, JavaScript Expressions v.v.. tại link bên dưới:https://facebook.github.io/react/docs/jsx-in-depth.html
Một số link tham khảo khác:
JSX Compiler
https://facebook.github.io/react/jsx-compiler.html
Hello again
Quay trở lại ví dụ Hello world trong phần 2, chúng ta thử thay đổi code theo JSX syntax<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-type' content='text/html; charset=utf-8'>
<title>Basic Example Hello world</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
<script type="text/jsx">
var HelloComponent = React.createClass({
render: function() {
return <div className="hello">Hello, {this.props.name}</div>
}
})
var helloEl = <HelloComponent name=' Phúng' />;
React.render(
helloEl,
document.body
);
</script>
</body>
</html>
- Lưu ý: như phần trên đã nêu, để render một React Component, thì tên Component đó phải bắt đầu bằng ký tự in hoa. Do đó ở đây
helloComponent
trở thànhHelloComponent
JSX and ES6
Nhờ vào JSX Transform mà chúng ta có một vài features trong ES6 như Arrow function và Concise methods- Arrow function: đặt biệt hữu ích khi kết hợp với
map
vàfilter
methods (Chúng ta sẽ có dịp trải nghiệm trong các bài viết sau) - Concise methods: chúng ta sẽ không còn cần cách viết
: function
trong object nữa.
Viết theo cách cũ
render: function() {
return <div className="hello">Hello, {this.props.name}</div>
}
Viết theo cách mới render() {
return <div className="hello">Hello, {this.props.name}</div>
}
Reactjs - Bài 2 - Helloworld - phần 2 - React Component
Dẫn nhập
Trong phần 1, chúng ta đã dùngReact.creatElement
để tạo ReactElement
và dùng React.render
để render ReactElement
và gắn vào Real DOM để hiển thị lên trang web. Trong phần 2 này, tôi muốn giới thiệu về ReactComponent
.Cũng cần nói thêm
ReactElement
thuộc thành phần cơ bản nhất của React. Nó có 4 properties: type, props, key và ref. Nó không có methods và prototype cũng không có gì cả.Với
ReactElement
cũng đủ cho bạn render một View, nhưng chúng ta sẽ không tận dung hết lợi điểm của React. Với ReactComponent
, chúng ta có thể tạo một sự bao đóng với embeded state
(trạng thái được nhúng).Ví dụ, trong ví dụ ở phần 1, chúng ta render ra được nội dung ‘Hello, world’ nhưng nếu chúng ta muốn thay đổi ‘Hello, world’ thành ‘Hello, Phung’ thì sẽ không được, trừ khi chúng ta sửa lại code, thay từ ‘world’ thành từ ‘Phung’. Như vậy chúng ta chỉ có được một ‘Static UI’.
Trong khi đó nếu dùng
ReactComponent
thì chúng ta có thể thay đổi ‘world’ thành ‘Phung’ thông qua embeded state
trong ReactComponent
, do đó chúng ta có thể tương tác và có được một ‘Dynamic UI’. Trước mắt hãy xem state
như là một đối số giúp ta có thể tương tác với UI.Get your hand dirty
Từ ví dụ ở phần 1, chúng ta thử đưa lần lần ReactComponent vào.Source code mẫu:
https://slack-files.com/T035VUSF2-F0559AYFY-60efc6e91b
Hãy xem
helloComponent
ở ví dụ trên var helloComponent = React.createClass({
render: function() {
return React.createElement('div', {className: 'hello'}, 'Hello, Phúng');
}
});
Format của nó như sau var MyComponent = React.createClass({
render: function() {
...
}
});
Khi tạo một Component Class bởi React.createClass(), ta sẽ cung cấp cho nó một object ( phần { … } ) cụ thể có chứa render
method và những methods khác.Như bạn thấy ở trên, React Component Class ở trên giống như là một Function mang theo
props
và state
(sẽ trình bày sau), và render HTML. Tiếp theo là
helloEl
được tạo từ React Component Class var helloEl = React.createElement(helloComponent);
Phần gắn helloEl
vào document.body
thì giống như đã trình bày trong phần 1. Với những giải thích ở trên hy vọng các bạn đã có một khái niệm sơ bộ về React Component. Tiếp theo ta đưa tên ‘Phúng’ ra khỏi
helloComponent
và thay vào đó là đối số this.props.name
sẽ được truyền vào. Source code:
https://slack-files.com/T035VUSF2-F055Y3SUF-8b903b5e26
Trong phần này có thêm một khái niệm mới là
props
. props
sẽ được giới thiệu chi tiết hơn trong bài viết sau, còn trong giới hạn của bài viết này tôi muốn bạn xem props
như là một “model” data trong React và Component sẽ lấy data từ props và render nó.
Đăng ký:
Bài đăng (Atom)