React for beginner
Bài đăng này đã không được cập nhật trong 7 năm
Giới thiệu
Bài viết này giới thiệu về các khái niệm tổng quát về React mà tôi đã tìm hiểu và tham khảo ở internet , nhằm mục đích giúp những người bắt đầu tìm hiểu về React .
-
React làm việc tốt với vai trò là View Layer
React không giống với các MVC framework hay với các framework javascript mà các bạn biết từ trước đây.Đơn giản ,nó là thư viện giúp người dùng thực hiện việc tạo ra các View dễ dàng hơn.
-
Xây dựng component trong ứng dụng với qui mô nhỏ
Với các developer thì việc chia nhỏ các class ,module là dễ dàng hơn để hiểu, kiểm tra, bảo trì, và điều này cũng đúng của component trong React.Tất nhiên, kích thước chính xác sẽ phụ thuộc vào nhiều yếu tố khác nhau (bao gồm sở thích cá nhân của bạn!).Ví dụ :
const LatestPostsComponent = props => (
<section>
<div><h1>Latest posts</h1></div>
<div>
{ props.posts.map(post => <PostPreview key={post.slug} post={post}/>) }
</div>
</section>
);
-
Function Component
Có 2 các để viết các function cho component, 1 là viết theo React.createClass()
const MyComponent = React.createClass({
render: function() {
return <div className={this.props.className}/>;
}
});
và cách thứ 2 là viết theo định dạng ES6
class MyComponent extends React.Component {
render() {
return <div className={this.props.className}/>;
}
}
React 0.14 đã giới thiệu 1 cấu trúc mới cho các component
const LatestPostsComponent = props => {
const postPreviews = renderPostPreviews(props.posts);
return (
<section>
<div><h1>Latest posts</h1></div>
<div>
{ postPreviews }
</div>
</section>
);
};
const renderPostPreviews = posts => (
posts.map(post => this.renderPostPreview(post))
);
const renderPostPreview = post => (
<article>
<h3><a href={`/post/${post.slug}`}>{post.title}</a></h3>
<time pubdate><em>{post.posted}</em></time>
<div>
<span>{post.blurb}</span>
<a href={`/post/${post.slug}`}>Read more...</a>
</div>
</article>
);
-
sử dụng propTypes
propTypes giúp các developer dễ dàng tạo thêm các component an toàn, và trông nó sẽ ntn:
const ListOfNumbers = props => (
<ol className={props.className}>
{
props.numbers.map(number => (
<li>{number}</li>)
)
}
</ol>
);
ListOfNumbers.propTypes = {
className: React.PropTypes.string.isRequired,
numbers: React.PropTypes.arrayOf(React.PropTypes.number)
};
1 số ích lợi của việc sử dụng propTypes:
- Có thê dễ dàng bắt đc lỗi 1 cách đơn giản
- Nếu bạn sử dụng attribute isRequired ,sẽ ko cần phải thực hiện việc check undeined hoặc null trong code
-
Thực hiện unit test cho React
Đúc kết từ nhiều tài liệu thì tôi nhận thấy có 3 cách thực hiện unit tests cho các component:
-
Render logic
Ví dụ với việc hiển thị 1 ảnh hoặc với loading icon, ta thực hiện như sau:
-
const Image = props => {
if (props.loading) {
return <LoadingIcon/>;
}
return <img src={props.src}/>;
};
thì ta sẽ thực hiện thao tác test như sau :
describe('Image', () => {
it('renders a loading icon when the image is loading', () => {
const image = shallowRender(<Image loading={true}/>);
expect(image.type).toEqual(LoadingIcon);
});
it('renders the image once it has loaded', () => {
const image = shallowRender(<Image loading={false} src="https://example.com/image.jpg"/>);
expect(image.type).toEqual('img');
});
});
- Biến đổi các Prop
const TextWithArrayOfClassNames = props => (
<div>
<p className={props.classNames.join(' ')}>
{props.text}
</p>
</div>
);
describe('TextWithArrayOfClassNames', () => {
it('turns the array into a space-separated string', () => {
const text = 'Hello, world!';
const classNames = ['red', 'bold', 'float-right'];
const textWithArrayOfClassNames = shallowRender(<TextWithArrayOfClassNames text={text} classNames={classNames}/>);
const childClassNames = textWithArrayOfClassNames.props.children.props.className;
expect(childClassNames).toEqual('red bold float-right');
});
});
- Tương tác với người dùng
Tất nhiên, các component không chỉ để trưng bày, chúng cũng được dùng để tương tác:
const RedInput = props => (
<input className="red" onChange={props.onChange} />
)
Dưới đây là cách yêu thích của tôi để test :
describe('RedInput', () => {
it('passes the event to the given callback when the value changes', () => {
const callback = jasmine.createSpy();
const redInput = shallowRender(<RedInput onChange={callback}/>);
redInput.props.onChange('an event!');
expect(callback).toHaveBeenCalledWith('an event!');
});
});
Tài liệu tham khảo:
All rights reserved