iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 23
0
Modern Web

30天React從入門到入坑系列 第 23

DAY23:React實作小專案(components實作)

昨天已完成layout與router,今天實作Notices(公告)、UserInfo(使用者清單)、PhoneInfo(電話清單)。主要運用先前react-bootstrap與fetch API取資料,來實作一個管理類型的網頁。

Notices Component

components/Notices.js

import React, { Component } from 'react';
import {Navbar, Nav, NavItem, Grid, Row, Col, Panel} from 'react-bootstrap'

class Notices extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const title = {
      paddingBottom: '9px',
      marginBottom: '20px',
      borderBottom: '1px solid #eee'
    };
    return (
      <div>
        <h1 style={title}>公告資訊</h1>
        <Grid fluid={true}>       
          <Row className="show-grid">
            <Col xs={8}>
              <Panel bsStyle="info">
                <Panel.Heading>
                  <Panel.Title componentClass="h3">2018/1/10 IT鐵人賽</Panel.Title>
                </Panel.Heading>
                <Panel.Body>趕搞中...</Panel.Body>
              </Panel>
            </Col>
          </Row>
          <Row className="show-grid">
            <Col xs={8}>
              <Panel bsStyle="info">
                <Panel.Heading>
                  <Panel.Title componentClass="h3">2018/1/9 IT鐵人賽</Panel.Title>
                </Panel.Heading>
                <Panel.Body>IT鐵人賽實作專案最後衝刺中!!!</Panel.Body>
              </Panel>
            </Col>
          </Row>
        </Grid>
      </div>
    );
  }
}

export default Notices;

UserInfo Component

components/UserInfo.js

import React, { Component } from 'react';
import {Navbar, Nav, NavItem, Grid, Row, Col, Table} from 'react-bootstrap'

class UserInfo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rsobj: {},
      isLoaded: false,
      error: null
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then((result) => {
          this.setState({
            isLoaded: true,
            rsobj: result
          });
        },(error) => {
          this.setState({
            isLoaded: true,
            error: error
          });
        }
      )
  }

  render() {
    const { isLoaded, error, rsobj } = this.state;
    const h1BottomHr = {
      paddingBottom: '9px',
      marginBottom: '20px',
      borderBottom: '1px solid #eee'
    };
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      const content = rsobj.map((rsobj, index) =>
        <tr key={index}>
          <td>{index}</td>
          <td>{rsobj.id}</td>
          <td>{rsobj.name}</td>
        </tr>
      );
      return (
        <div>
          <h1 style={h1BottomHr}>使用者清單</h1>
          <Grid fluid={true}>
        		<Row className="show-grid">
        			<Col xs={6}>
                <Table striped bordered condensed hover>
              		<thead>
              			<tr>
              				<th>#</th>
              				<th>id</th>
              				<th>Username</th>
              			</tr>
              		</thead>
              		<tbody>
              	     {content}
              		</tbody>
              	</Table>
        			</Col>
        		</Row>
      		</Grid>
        </div>
      );
    }
  }
}

export default UserInfo;

PhoneInfo Components

components/PhoneInfo.js

import React, { Component } from 'react';
import {Navbar, Nav, NavItem, Grid, Row, Col, Table} from 'react-bootstrap'

class PhoneInfo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rsobj: {},
      isLoaded: false,
      error: null
    };
  }

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then((result) => {
          this.setState({
            isLoaded: true,
            rsobj: result
          });
        },(error) => {
          this.setState({
            isLoaded: true,
            error: error
          });
        }
      )
  }

  render() {
    const { isLoaded, error, rsobj } = this.state;
    const title = {
      paddingBottom: '9px',
      marginBottom: '20px',
      borderBottom: '1px solid #eee'
    };
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      const content = rsobj.map((rsobj, index) =>
        <tr key={index}>
          <td>{index}</td>
          <td>{rsobj.name}</td>
          <td>{rsobj.phone}</td>
        </tr>
      );
      return (
        <div>
          <h1 style={title}>電話清單</h1>
          <Grid fluid={true}>
        		<Row className="show-grid">
        			<Col xs={6}>
                <Table striped bordered condensed hover>
              		<thead>
              			<tr>
              				<th>#</th>
              				<th>Username</th>
              				<th>phone</th>
              			</tr>
              		</thead>
              		<tbody>
              	     {content}
              		</tbody>
              	</Table>
        			</Col>
        		</Row>
      		</Grid>
        </div>
      );
    }
  }
}

export default PhoneInfo;

Notices畫面
https://ithelp.ithome.com.tw/upload/images/20180111/20107317RIrbOVcZAK.png

UserInfo畫面
https://ithelp.ithome.com.tw/upload/images/20180111/20107317qPreEj4Uia.png

待解問題

  1. component使用css物件修改為css file使用className
  2. 圖片路徑問題無法直接使用
  3. 網頁刷新出現404

明天加入新的loader調整webpack參數,就初步完成此專案實作。如後續有發現問題再逐步調整,對初心者來講很難一開始什麼都想好,只能逐步調整慢慢重構。初心者入坑之日好像不遠了,明天一併附上git repository。


上一篇
DAY22:React實作小專案(layout實作)
下一篇
DAY24:React實作小專案(webpack調整)
系列文
30天React從入門到入坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言