React for beginner

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 .

  1. 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.

  2. 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>
    );
  1. 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>
    );
  1. 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
  1. 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: