iT邦幫忙

0

Day55 (React)

  • 分享至 

  • xImage
  •  

1.React導引 (JS框架)

(Lab_Hello > index.html)

(1)安裝/引用 React 的 JavaScript
development.js 核心功能
react-dom.development.js UI處理;把虛擬的dom轉為實體

    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>    

(2)寫入內容
(2-1)ReactDOM.render(在React核心建立一個元素,放到這)--->渲染/動態

    <div id="root"></div>

    ReactDOM.render(
    React.createElement("h1", null, "Hello, world!"),
    document.getElementById("root"));

(2-2)使用翻譯html MOD => babel.min.js

   <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">   //type="text/babel" 必要 babel.min.js才敢介入
      ReactDOM.render(
            <h1>Hello, world!</h1>, 
            document.getElementById("root")
      );
    </script>

(2-3)建立一個App元件,在React.Component裡 並 使用babel.min.js翻譯html

   <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">
      class MyApp extends React.Component {
        // 建立一個App元件,在React.Component裡
        render() {
          return <h1>Hello world!</h1>;
        }
      }
       // ReactDOM.render(元件,輸出ID)
      ReactDOM.render(<MyApp />, document.getElementById("root"));
    </script>

2.物件製作淺規則------------------------------>重要

第一個字都要大寫

(1)React - Calss版本

製作Clock元件(物件)繼承React.Component
使用時須super()引用想使用的屬性
state是內建的,無須引用

      //使用React.Component製作Clock元件(物件),props這個MOD的方法,新增this.state屬性
      class Clock extends React.Component {
        constructor(props) {
          // constructor: 製作預設值
          super(props); //React.Component裡面的props先抓出來給自己(Clock) ; 父親
          
          // state建議不要改名
          this.state = { date: new Date() }; //利用props增加一個屬性state狀態
       }

(2)React - function版本

不須constructor:預設

      function Welcome(props) {
        return (
          <h1>
            Hello, {props.FirstName}, {props.LastName}
          </h1>
        );
      }

      const element = (
        <div>
          <Welcome FirstName="Jeter" LastName="111" />
          <Welcome FirstName="Messi" LastName="111" />
          <Welcome FirstName="Jordan" LastName="111" />
        </div>
        // FirstName="Jeter" key : vaule
      );

      ReactDOM.render(element, document.getElementById("root"));

Js

      function Student(sname, sage) {
        // Student = {x:y}
        this.StudentName = sname; //this S = x
        this.StudentAge = sage; //this S = y

        this.cat = function () {
          console.log("喵");
          console.log(this.StudentName); //物件裡面的屬性 this
        };
      }

3.React的元件製作MOD - Simple React Snippets

(Lab_Hello_Toolchain > Lab > hello)

Simple React Snippets 協助產生元件的MOD

(1)安裝 create-react-app 全域安裝

 > npm install create-react-app -g

(2)切換到習慣的工作目錄,啟動「命名提示字元」,建立react資料夾
C:\XXX\react_part_1\Lab_Hello_Toolchain\Lab

 > create-react-app hello

Happy hacking!>{}<(會安裝很久。)

會建立一個新的資料夾: C:\XXX\react_part_1\Lab_Hello_Toolchain\Lab\hello

(3)C:\XXX\react_part_1\Lab_Hello_Toolchain\Lab\hello下執行

      package.json  "scripts": {
        "start": "react-scripts start",
      },

npm start

會出現
https://ithelp.ithome.com.tw/upload/images/20210824/20137684gZyO8HJWZ3.png
或手動執行http://localhost:3000/

(4)觀察專案

(4-1)public > index.html

主畫面

(4-2)src > App.js

App.js = App元件<App />

所以改變內容網頁也會改變

(4-3)src > index.js

把網頁鑲嵌近來

    ReactDOM.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
      document.getElementById('root')
    );

(5)將 src 資料夾的全部檔案都刪除

(6)src內新增index.js

   import React from 'react';
   import ReactDOM from 'react-dom';

   const element = <h1>Hello World</h1>;
   ReactDOM.render(element, document.getElementById("root"));

npm start

Hello World出現~~~~~

(7) Ctrl + C 結束 Development Server.

(8)安裝與使用 Bootstrap

npm install bootstrap@4.1.1

(9)src內更改index.js
display-1為BS樣式

    import React from 'react';
    import ReactDOM from 'react-dom';
    import "bootstrap/dist/css/bootstrap.css";

    // h1 class="display-1"一樣可執行,className特意區分Class,讓工程師比較好辨識
    const element = <h1 className="display-1">Hello World</h1>;
    ReactDOM.render(element, document.getElementById("root"));

npm start

(10) Ctrl + C 結束 Development Server.

以下解釋「放到MAMP亦可執行」---->失敗?需提問:問不出來,自己找XD

(11) 編譯與佈署 React 應用程式

npm run build

新增資料夾build
C:\XXX\react_part_1\Lab_Hello_Toolchain\Lab\hello\build

(12)將 build 資料夾複製到 c:\MAMP\htdocs

c:\MAMP\htdocs\build
build改名hello
c:\MAMP\htdocs\hello

(13)C:\MAMP\conf\apache\httpd.conf
將下列內容,附加到檔案結尾處

    LISTEN 8001
    <VirtualHost *:8001>
        DocumentRoot "C:\MAMP\htdocs\hello"
    </VirtualHost>

http://localhost:8001/

(14)練習結束

還原 C:\MAMP\conf\apache\httpd.conf 檔案內容
刪除 hello 資料夾

因此,想要使用React放到apache可執行時
先用build打包,後放到c:\MAMP\htdocs內(似PHP)
更改httpd.conf port號的路徑,即可使用


4.class有分美術樣式(CSS)或是後端類別

美術樣式(CSS .class):
className特意區分Class,讓工程師比較好辨識

    const element = <h1 className="display-1">Hello World</h1>;
    ReactDOM.render(element, document.getElementById("root"));

後端類別(class):
React

      class MyApp extends React.Component {
        //  創一個 名為MyApp的類別 繼承自 React.Component
        //  並使用React.Component 裡的render() 方法
        //  命名:開頭大寫
        render() {
          return <h1>Hello world!</h1>;
        }
      }

5.React - JSX :好維護的 HTML 架構

(Lab_JSX > index_0.html)

(1)先試試看之前呼叫的用法
Lab_JSX > index_0.html
計算 + 網頁 + 資料

(2)在 JSX 呼叫函式

      const dataItem = {
        scientificName: "Everes lacturnus rileyi",
        commonName: "南方燕藍灰蝶",
      };


      function formatName(species) {

           // 1.JSX版
           return (
           <span>
           {species.commonName} <br /> {species.scientificName}
           </span>
           );
        

           // 2.字串版
           // 字串版  ,<br>無效 無法換行
           // return `${species.commonName} <br /> ${species.scientificName}`;
           }


           // 3.JSX版 + 判別式
           var x = 100;
           if (x >= 100) {
           return ( //return不行去掉;(),會變成 return;(Js的特性,會幫忙加;)
            <span>
              {species.commonName} <br /> {species.scientificName}
            </span>
           );
             } else {
          return <div> 值未達100時 </div>;
             }
          }
        
      const element = <h3> {formatName(dataItem)} </h3>;
若不想使用const element = <h3> {formatName(dataItem)} </h3>;
把字串改成元件
      const element = (
        <div>
          {dataItem.commonName} <br /> {dataItem.scientificName}
        </div>
      );

(3)新增照片

      const element = (
        <div className="col-4">
          <h3> {formatName(dataItem)} </h3>
          <img src="images/rileyi.jpg" />
        </div>
        // <img src={dataItem.image}  />      ,  需加  "/"
        // <img src= {dataItem.image} ></img> , 或需加</img>
      );

6.空白的換行,js特性(幫忙加;)會製造bug

      function formatName(species) {
         return (  //正確
           <span>
             {" "}
             {species.commonName} <br /> {species.scientificName}{" "}
           </span>
         );

此處return不行去掉;(),會變成 return; (Js的特性,會幫忙加; 這個程式就不會往下跑了(return))

      function formatName(species) {
         return //錯誤 
           <span>
             {" "}
             {species.commonName} <br /> {species.scientificName}{" "}
           </span>
      }

7.React - render

(Lab_Render > index_0.html)

      function displayTime() {
        const element = (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {new Date().toString()}.</h2>
          </div>
        );
        ReactDOM.render(element, document.getElementById("root"));
      }

      setInterval(displayTime, 1000);

非ajax,只是一般的setInterval


8.render()

通常將虛擬轉成實體的關鍵字,如ejs
10.ajax
可以去撈後端資料,隨時更新


9.React - Props 製作物件資料們

(Lab_Render > index_0.html)
想法:Props是一種MOD,她有偷偷動手腳讓我可以直接呼叫物件

(1)Welcome元件製作:

       class Welcome extends React.Component {
          render() {
            return (
              <h1>
                Hello, {this.props.FirstName} , {this.props.LastName}
              </h1> // props取自React.Component的屬性及值
            ); //大小寫注意
          }
        }

或是這樣寫也對

      function Welcome(props) {
        return (
          <h1>
            Hello, {props.FirstName}, {props.LastName}
          </h1>
        );
      }

(2)在Welcome元件放入資料 FirstName="Jeter" key : vaule

      const element = (
        <div>
          <Welcome FirstName="Jeter" />
          <Welcome FirstName="Messi" />
          <Welcome FirstName="Jordan" />
        </div>
      );

      ReactDOM.render(element, document.getElementById("root"));

10.state + props + setState 製作隨時更新的內容

(Lab_Render > Lab_State_LifeCycle)
注意:只能輸出給id

1.ReactDOM.render要輸出的時候,會先根據製作物件

    ReactDOM.render(<Clock />, document.getElementById("root")); 

2.製作Clock元件(物件),props這個MOD的方法,新增this.state屬性

       class Clock extends React.Component {
        constructor(props) {
          super(props);
          //state不要改名
          this.state = { date: new Date() }; //利用props增加一個屬性state
       }

製作元件方式,有兩種Class及function方式製作

(2-1)Class : constructor:預設

      class Car {
        constructor(changecolor, changewheels) {
          // this.color 原本設定的
          // var myCar = new Car("green");
          this.color = changecolor; //顏色
          this.wheels = changewheels; //輪子
        }

        showInfo() {
          console.log(this.color);
          console.log(this.wheels);
        }
      }

      var myCar = new Car("green", 4);
      myCar.showInfo();

Class可以繼承extends React.Component而取得使用內建的屬性
使用時須super()引用

      // constructor: 建立 ; 當建立 類別物件時 會自動產生constructor裡面的內容
      class Clock extends React.Component {
        constructor(props) {
          super(props); //React.Component裡面的props先抓出來給自己 ; 父親
          //state建議不要改名
          this.state = { date: new Date() }; //利用props增加一個屬性state狀態
        }

(2-2)function

不須constructor:預設

      function Welcome(props) {
        return (
          <h1>
            Hello, {props.FirstName}, {props.LastName}
          </h1>
        );
      }

      const element = (
        <div>
          <Welcome FirstName="Jeter" LastName="111" />
          <Welcome FirstName="Messi" LastName="111" />
          <Welcome FirstName="Jordan" LastName="111" />
        </div>
        // FirstName="Jeter" key : vaule
      );

      ReactDOM.render(element, document.getElementById("root"));

3.元件的render()方法呼叫

        render() {  
          return (
            <div>
              <h1>Hello, world!</h1>
              <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
            </div>
          );
        }

4.網頁內容放進document.getElementById("root"))

    ReactDOM.render(<Clock />, document.getElementById("root")); 

5.當元件 放到id=root後 react 會自動去找有無componentDidMount() 方法

     componentDidMount() {
          this.timerId = setInterval(() => {
            // 開始計時
            // 寫法1:
            // this.state.date = new Date();  // 單純只有屬性給Date() 網頁不會刷新
            // this.setState(this.state.date); 
            // 當「 狀態或資料要改變 」時,需使用.setState() 方法讓他去呼叫render()「 重新產生畫面 」

            // 寫法2:
            // this.setState({ date: new Date() }); //把上面 兩行寫成一行

            // 寫法3:
            this.state.date = new Date(); //單純只有屬性給Date() 網頁不會刷新
            this.setState({}); //使用空物件,react 也會自動去偵測要改變的屬性
          }, 1000);
        }

6.當網頁或元件 即將卸載或網頁關掉後 react 會自動去找有無 componentWillUnmount()方法

        componentWillUnmount() {
          clearInterval(this.timerId); // 停止記時
        }

setState() 執行順序

  class Clock extends React.Component {
        constructor(props) {
          super(props); 
          // 1. <Clock/>繼承父層的state屬性,用來搭配setState()方法用
          this.state = { date: new Date() };
        }
        
  componentDidMount() {
          this.timerId = setInterval(() => {    
            // 2. 單純只有屬性給Date() 網頁不會刷新
            this.state.date = new Date(); 
            
            this.setState({ date: new Date() }); // 3. 抓改變而刷新
            
            // 4. 方法名稱 和 同名的屬性名稱{ date: new Date() } 做對應
            // this.setState({});使用空物件,react 也會自動去偵測要改變的屬性
            
          }, 1000);
        }
        
      render() {
          return (
            <div>
              <h1>Hello, world!</h1>
              //5. 字串輸出
              <h2>It is {this.state.date.toLocaleTimeString()}.</h2> 
            </div>
          );
        }
        
     //6. 網頁內容放進document.getElementById("root"))
     ReactDOM.render(<Clock />, document.getElementById("root"));

11. Q:setInterval 那邊,請問一定要箭頭函式的寫法嗎?

是,如果用function,this會搞丟

            componentDidMount() {
                this.timerId = setInterval( () => {
                    this.setState({ date: new Date() });
                }, 1000);
            }

12.State(狀態) vs props(屬性)

State(狀態) => 內建
props(屬性) => 跟父親繼承

      class Clock extends React.Component {
        constructor(props) {

          // constructor: 製作預設值
          super(props); //React.Component裡面的props先抓出來給自己(Clock) ; 父親

          // state建議不要改名
          this.state = { date: new Date() }; //利用props增加一個屬性state狀態
        }

13.render id的方式

   <script type="text/babel">
      function Myapp() {
        return (
          <div>
            <ul>
              <li>1</li>
              <li>2</li>
              <li>3</li>
            </ul>
            <ol>hi</ol>
          </div>
        );
      }

      ReactDOM.render(<Myapp />, document.getElementById("root"));  //方法1.
      ReactDOM.render(<Myapp />, root);  //方法2.

14.解釋

套件:小工具包
框架:套件的進階版,可用來完成一個專案
api:別人寫好的方法
api文件:使用說明書


class是類別、function()是方法
class是透過繼承 React.Component => 把class類別變成元件了
元件 是 框架的專有名詞
元件 想成 標籤元素
而 function() 則是 透過 React 自身 把它變成元件了
變成 我們一般 html的那種標籤

       class Clock extends React.Component {
        constructor(props) {
          super(props);
          //state不要改名
          this.state = { date: new Date() }; //利用props增加一個屬性state
       }

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言