React.js component xử lý data

React.js component xử lý data

  • Bài học trước ta đã biết các xử lý data đơn giản cho một component, bài học này sẽ giúp các bạn hình dung được các dữ liệu được truyền giữa các component như thế nào.
  • Sử dụng lại kết quả ví dụ của bài React.js Component ta có:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="member"></div>

    <script type="text/babel">
      function Avatar(){
        return(
          <div className="avatar">
            <img src="img_avatar.jpg" alt="" />
          </div>
        )
      };

      function MemberInfo(){
        return(
          <div className="info">
            <h2>Nguyễn Văn A</h2>
            <p>Tuổi: 25</p>
          </div>
        )
      };

      function Comment(){
        return(
          <div className="comment">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.
          </div>
        )
      };

      function Member(){
        return(
          <div className="member">
            <Avatar />
            <MemberInfo />
            <Comment />
          </div>
        )
      };

      ReactDOM.render(
        <Member />,
        document.getElementById('member')
      );
    </script>
  </body>
</html>

Hiển thị trình duyệt

Nguyễn Văn A

Tuổi: 25

Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.

Làm thử!

  • Tạo một data object như sau:
const member = {
  text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.',
  info: {
    path: 'img_avatar.jpg',
    name: 'Nguyễn Văn A',
    age: 25
  }
}
  • Lần lượt tiến hành xử lý dữ liệu trong các function như sau:
function Avatar(props){
  return(
    <div className="avatar">
      <img src={props.info.path} alt="" />
    </div>
  )
};

function MemberInfo(props){
  return(
    <div className="info">
      <h2>{props.info.name}</h2>
      <p>Tuổi: {props.info.age}</p>
    </div>
  )
};

function Comment(props){
  return(
    <div className="comment">
      {props.text}
    </div>
  )
};

function Member(){
  return(
    <div className="member">
      <Avatar info={member.info} />
      <MemberInfo info={member.info} />
      <Comment text={member.text} />
    </div>
  )
};
  • {props.info.path} props sẽ lấy giá trị path từ info của dữ liệu, tương tự cho nameage.
  • {props.text} giá trị text được lấy trực tiếp.
  • <Avatar info={member.info} /> cần khai báo các giá trị dữ liệu tương ứng, tương tự cho function <MemberInfo /><Comment />.

Khi này trình duyệt vẫn cho kết quả

Nguyễn Văn A

Tuổi: 25

Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.

Làm thử!

Xử lý dữ liệu khi các component lồng vào nhau (tái sử dụng component)

  • Để hiểu rõ hơn việc truyền dữ liệu giữa các component, ta tiến hành lồng function Avatar(props) vào bên trong MemberInfo(props), ta làm như sau (nhớ xóa bỏ function Avatar(props) bên trong Member()):
function Avatar(props){
  return(
    <div className="avatar">
      <img src={props.info.path} alt="" />
    </div>
  )
};

function MemberInfo(props){
  return(
    <div className="info">
      <Avatar info={member.info} />
      <h2>{props.info.name}</h2>
      <p>Tuổi: {props.info.age}</p>
    </div>
  )
};

function Comment(props){
  return(
    <div className="comment">
      {props.text}
    </div>
  )
};

function Member(){
  return(
    <div className="member">
      <MemberInfo info={member.info} />
      <Comment text={member.text} />
    </div>
  )
};
  • Việc di chuyển <Avatar info={member.info} /> từ function Member() vào bên trong MemberInfo(props). Khi này kết quả vẫn không thay đổi.
  • Thay vì sử dụng member.info của function <Avatar />, ta sẽ liên kết <Avatar /> với <MemberInfor /> bằng một props.avatar, với avatar là một tên bất kỳ được sử dụng riêng bên trong function <Avatar />, ta viết như sau:
function Avatar(props){
  return(
    <div className="avatar">
      <img src={props.avatar.path} alt="" />
    </div>
  )
};

function MemberInfo(props){
  return(
    <div className="info">
      <Avatar avatar={props.info} />
      <h2>{props.info.name}</h2>
      <p>Tuổi: {props.info.age}</p>
    </div>
  )
};
  • avatar ta có thể đặt tên bất kỳ, miễn sao ở function <MemberInfor /> ta gọi kết quả trả về là props.info là được. Điều này tiện lợi trong việc xử lý các giá trị props ở các component mà không cần quan tâm tới các giá trị props ở các component khác.
  • Code hoàn chỉnh khi này ta có:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
    <div id="member"></div>

    <script type="text/babel">
      function Avatar(props){
        return(
          <div className="avatar">
            <img src={props.avatar.path} alt="" />
          </div>
        )
      };

      function MemberInfo(props){
        return(
          <div className="info">
            <Avatar avatar={props.info} />
            <h2>{props.info.name}</h2>
            <p>Tuổi: {props.info.age}</p>
          </div>
        )
      };

      function Comment(props){
        return(
          <div className="comment">
            {props.text}
          </div>
        )
      };

      function Member(){
        return(
          <div className="member">
            <MemberInfo info={member.info} />
            <Comment text={member.text} />
          </div>
        )
      };

      const member = {
        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.',
        info: {
          path: 'img_avatar.jpg',
          name: 'Nguyễn Văn A',
          age: 25
        }
      };

      ReactDOM.render(
        <Member />,
        document.getElementById('member')
      );
    </script>
  </body>
</html>

Hiển thị trình duyệt

Nguyễn Văn A

Tuổi: 25

Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.

Làm thử!

  • Ta cũng có thể làm tương tự cho component MemberInfo(props)Member(), ta tiếp tục viết lại code như sau:
function MemberInfo(props){
  return(
    <div className="info">
      <Avatar avatar={props.memberInfo} />
      <h2>{props.memberInfo.name}</h2>
      <p>Tuổi: {props.memberInfo.age}</p>
    </div>
  )
};

function Member(){
  return(
    <div className="member">
      <MemberInfo memberInfo={member.info} />
      <Comment text={member.text} />
    </div>
  )
};

Hiển thị trình duyệt

Nguyễn Văn A

Tuổi: 25

Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.

Làm thử!

  • Với memberInfo là tên bất kỳ bên trong component MemberInfo(props).

Xử lý dữ liệu tại phần render

  • Hiện tại giá trị dữ liệu object const member được gọi trực tiếp bên trong Member(), ta có thể gọi giá trị này tại phần render, mục đích để tách biệt rõ các component chỉ nên xử lý các thao tác logic, phần dữ liệu nên đặt tại render.
  • Ta viết lại component Member() và phần render như sau:
function Member(props){
  return(
    <div className="member">
      <MemberInfo memberInfo={props.info} />
      <Comment text={props.text} />
    </div>
  )
};

ReactDOM.render(
  <Member 
    info={member.info}
    text={member.text}
  />,
  document.getElementById('member')
);

Hiển thị trình duyệt lúc này vẫn không thay đổi

Nguyễn Văn A

Tuổi: 25

Lorem ipsum dolor sit amet, consectetur adipiscing elit proin sit amet neque.

Làm thử!

  • Qua bài này ta thấy giá trị của Props không thay đổi, chỉ truyền từ component này sang component khác, giá trị dữ liệu phụ thuộc vào dữ liệu object khai báo ban đầu, ví dụ đơn giản: muốn thay đổi giá trị dữ liệu "Nguyễn Văn A" thành "Nguyễn Thị B" bên trong component MemberInfo(props) thì ta làm như thế nào? tất nhiên với props ta không thể thực hiện được.
  • Để giải quyết bài toán dữ liệu có thể thay đổi được trong quá trình truyền dữ liệu giữa các component, React cho ra một khái niệm khác, đó là State, bài học sau ta sẽ làm quen với State nhé.