iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0
Modern Web

為期 30 天的 react 大冒險系列 第 10

react 大冒險-將 App component 改寫成 class component-day 9

class component

將原本的 App.js 改寫如下..

import React from 'react';

class App extends React.Component {
  render() {
    return (
      <>
        <p>hello world!</p>
      </>)
  }
}

export default App;

存檔後瀏覽器重新整理,畫面顯示出
image alt
看起來跟最初的 functional component 沒兩樣,就表示成功將 App component 改寫為 class component

class ComponentName extends React.Component

class component 似乎看起來有種似曾相識的感覺..
其實 class component 就是使用 es6 中 class 的概念
在 es6 的 class 中類別繼承的寫法為 子類別 extends 父類別

es6 的 class..

class UserName{
    constructor(firstName,lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }
    getName(){
        return `${this.firstName} ${this.lastName}`
    }
}

class WorkerName extends UserName{
    constructor(firstName ,lastName , job){
        super(firstName , lastName);
        this.job = job;
    }
}

const Harrison = new WorkerName('Harrison' , 'Huang' , 'driver');
console.log(Harrison.getName()); //  output: "Harrison Huang";

而 react 中 class component 就是 新建立的 class Component 去繼承在 React 內定義的 Component 內容

import Reat from 'react';

class App extends React.Component{
    ...
}

import Reat ,{Component} from 'react';

class App extends Component{
    ...
}

使用 array map 從靜態資料生成 component 的內容

除了手動在 jsx 中添加固定數量的內容外,也可以用靜態資料搭配 array method 來生成內容
添加型別為陣列的靜態資料 list
並在 return 中添加 array.map ,所有變數的地方都需要用 {} 包起來

import React from 'react';
const list = [
  {
    title: 'React',
    url: 'https://reactjs.org',
    objectID: 0
  },
  {
    title: 'Redux',
    url: 'https://redux.js.org',
    objectID: 1
  }
];

class App extends React.Component {
  render() {
    return (
      <>
        {list.map((item) => (
          <li>
            <strong>{item.title}</strong>
            <span>{item.url}</span>
          </li>))}
      </>)
  }
}

export default App;

接下來會看到

成功從 list 建立出頁面上的內容

題外話,同時在這裡開啟 developer tool 會發現有個錯誤
這個錯誤的意思是,react 會要求在列表中的 child 要擁有獨一無二的 key
現在先不解決,後面的篇幅會再提及

但隨著應用程式複雜度提升,jsx 看起來就會變得很凌亂
所以可以將內容拆分出去,放到其他 component 裡,再用引入的方式放到 App component 中

建立其他 component,並將 component import 到 App component 中

在 src 資料夾中建立新的 js
試試看用 arrow function 來寫 名為 ListItem 的 function components
ListItem.js 內

import React from 'react';

const ListItem = () => {
    return (
        <li>
            <b>ListItem title</b>
            <span>ListItem information</span>
        </li>
    )
}

export default ListItem;

回到 App.js
如同 import React from 'react'; 將 ListItem 引入到 component 裡
會發現有兩種 import 的形式

import React from 'react';
import ListItem from './ListItem';

「./」 的就是 js 檔
只有 「字串」的是 modules (也就是裝在 node_modules 裡面的 package)

import & export

import 跟 export 這些方法,讓 js 程式碼可以切分成不同的檔案跟模組(module)
import 跟 export 匯出/入 的內容可以是 function / primitive value / object ...
前情提要,在 es5 中,匯入的語法是

var React = require('react');
var ListItem = require('./ListItem');

es5 匯出

module.export("ListItem");

而在es6 時改為 import / export

import 單項及多項

  • import 單項
import defaultItem from './defaultItem';
  • import 多項
import { itemA,itemB } from './defaultItem';

export 單項及多項

  • export 單項 (default export)
export default defaultItem;
  • export names 多項 (standard export)(順序沒關係)
export { itemA , itemB };

重複使用 components

在 App.js 的 return 中輸入 <ListItem />

import React from 'react';
import ListItem from './ListItem';
const list = [
  {
    title: 'React',
    url: 'https://reactjs.org',
    num_comments: 3,
    objectID: 0
  },
  {
    title: 'Redux',
    url: 'https://redux.js.org',
    num_comments: 2,
    objectID: 1
  }
];


class App extends React.Component {
  constructor(props) {
    super(props);
    this.list = list;
  }
  render() {
    return (
      <>
        {list.map((item) => (
          <ListItem />
        ))}
      </>)
  }
}

export default App;

存檔後畫面重整,頁面上顯示出數個 ListItem component
image alt


上一篇
react 大冒險- React 的特殊寫法 JSX-day 8
下一篇
react 大冒險-prop / state & defaultProps-day 10
系列文
為期 30 天的 react 大冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言