iT邦幫忙

2023 iThome 鐵人賽

DAY 3
0

開始一個React的開發,請先看看你的專案內 package.json
先看看自己是有甚麼功能已經在裡面了。可以檢查一下
發現我們的react 是版本18.2.0 ㄝ

React的元件,其實就是基於html元件,加上點點規則:

  • 一個元件的class不能打class,要打className,
  • inner-style基本上要用JSON的型態來寫
  • inner-style不能用important
  • 元件必須有頭有尾 ex: , ,
  • 元件屬性有大小寫區分
    這就是為甚麼我會說有好的編譯器比較順手,有些規則會提醒你。

React程式,可以理解為大量堆疊的小程式
繼承昨天的 app.js

直接刪掉 <div className="App"></div> 裡面的所有東西,因為我想把常見的元件都丟進去吧

<div className="App">
    <header>我是頭部</header>
    <footer>我是腿部</footer>
    <address>地址</address>
    <table>
        <tr>
            <td>表格</td>
        </tr>
    </table>
    <li>asdf</li>
</div>

身為一個假裝優秀的前端工程師 開著開發人員工具 是很正常的 如果是Chrome,FireFox 按F12可以看到
噴錯了!?!?
A: 是那個幾乎沒看過的address搞的鬼?

B: address只是一個現在幾乎不用的html元件
真正噴錯的是 table

A: 啥? 我hmlt寫著麼久了 從來沒錯過,是甚麼道理

B: 是因為react的點點規則包含元件必須依順序擺放

A: 啥? 我table > tr > td 依序擺放 哪裡錯了?

B: react的table順序必須是 table > thead/tbody/tfoot > tr > td/th

A: 啥 我寫著麼久了 還真的沒用過tbody

B: 順帶一提ul li 的li可以單獨使用喔。

沒錯React讓人吐血的地方,元件的依序擺放,


說道Li 最常使用的dropDown下拉, Navbar導覽列 常常是用"特定規則"的排序

我們可以設計一個導覽列元件

<button>切換登入狀態</button>
<nav>
    <ul>
        <li><a href="連結A">首頁</a></li>
        <li><a href="連結B">關於我們</a></li>
        <li><a href="連結C">頁面C</a></li>
        <li><a href="連結D">登入</a></li>
    </ul>
</nav>

現在有個小小的問題,登入不是隨時需要,所以我們在開頭引用功能 並且宣告參數
開頭

import React, { useState } from "react";

函數

function App() {
    const [isLogin, setIsLogin] = useState(false);
    const [navBar, setNavBar] = useState([]);

    return (

有了參數,現在要執行參數控制

對按鈕加入監聽事件

<button onClick={() => setIsLogin(!isLogin)} >切換登入狀態</button>

告訴li 如果他是登入?不要顯示登入:改顯示登出

<nav>
    <ul>
        <li><a href="連結A">首頁</a></li>
        <li><a href="連結B">關於我們</a></li>
        <li><a href="連結C">頁面C</a></li>
        {isLogin ?
            <li><a href="SignOut">滾出</a></li>
            :
            <li><a href="Login">登入</a></li>}
    </ul>
</nav>

這樣按下按鈕 就能自動消滅的不用的那個區塊,
想想以前要常常getElement再createElement再append 淚~

三元運算子 超級常用!!
條件 ? 成功執行 :失敗執行

上面除了登入登出,網頁連結都還滿工整的
順便打包一下

const [navBar, setNavBar] = useState([
    {
        page: '首頁',
        url: '連結A',
    },
    {
        page: '關於我們',
        url: '連結B',
    },
    {
        page: '頁面C',
        url: '連結C',
    },
]);

下面nav修改一下

<nav>
    <ul>
        {navBar && navBar.length ?
            navBar.map((x, i) => (
                <li key={x['id']} href={x['url']}>{x['page']}</li>
            ))
            :null}
        <li><a href="連結A">首頁</a></li>
        <li><a href="連結B">關於我們</a></li>
        <li><a href="連結C">頁面C</a></li>
        {isLogin ?
            <li><a href="SignOut">滾出</a></li>
            :
            <li><a href="Login">登入</a></li>}
    </ul>
</nav>

會發現 上面區塊生出來的跟下面手寫的,一模一樣。
批量生成元件 可以用map((元素,順序)=>(html元件))

注意一下 在react 對於 ' " 比較不敏感,通常只要湊對就可了
但是()[]{} 個別代表不同意義,一般狀況都不能交換使用了,React裡更是不行
但你非得要用{}來寫map可以改成的話

navBar.map((x, i) => {
    let isActive=false;
    if(window.location.href==x['url']){isActive=true;}
    return 
        <li className={isActive?'Active':''} key={x['id']}><a href={x['url']}>{x['page']}</a></li>
    })

反倒是發現在使用{}的情況下 還能順便增加函數運算部分
不過要注意他的計算裡面更新參數 諸如useState或有其他參數,容易有問題。
(!在此舉例的相同網址是非常粗陋的寫法,太多例外沒有處理,但僅僅為舉例!)

因為nav 是相當重複的元件 每個地方常用到 所以我要打包他
app.js 將原本的nav整塊剪下來 由自定義元件 負責管理

<div className="App">
    <button onClick={() => setIsLogin(!isLogin)} >切換登入狀態</button>
    <Navbar />
</div>

最後將這個元件 命名為NavBar 請務必注意 必需是**"大寫"**開頭

  1. 新增目錄 "component"在 src底下
  2. 新增檔案 NavBar.js (請注意Big5,UTF-8的問題)
    圖片001
    請注意一下 app.js與 NavBar.js的相對路徑
    因為我們要import使用他
    在我檔案位置 =>.
    下面的 => /
    資料夾component => component
    的檔案NavBar.js => NavBar (.js勒 被偷懶偷走了)
import Navbar from './component/NavBar'

檔案 NavBar.js

import React, { useState } from "react";
function NavBar() {
    const [isLogin, setIsLogin] = useState(false);
    const [navBar, setNavBar] = useState([
        {
            id: '1',
            page: '首頁',
            url: '連結A',
        },
        {
            id: '2',
            page: '關於我們',
            url: '連結B',
        },
        {
            id: '3',
            page: '頁面C',
            url: '連結C',
        },
    ]);

    return (
        <nav>
            <ul>
                {navBar && navBar.length ?
                    navBar.map((x, i) => (
                        <li key={x['id']}><a href={x['url']}>{x['page']}</a></li>
                    ))
                    : null}
                {isLogin ?
                    <li><a href="SignOut">滾出</a></li>
                    :
                    <li><a href="Login">登入</a></li>}
            </ul>
        </nav>
    );
}
export default NavBar;

就會發現 NavBar被順利打包出去了
可以看見一個div裝著html元件跟自訂元件

然後return到哪?
就跟剛剛引用NavBar一樣,有檔案引用了app.js
所以這裡牽涉到react的規劃,是一層層往內嵌套,我們看見的app.js是內層,至於外層是誰?
在這個新安裝的專案直接安裝翻查檔案 index.js
可以看見

root.render(
    <BrowserRouter>
        <Routes>
            <Route path='/' element={<App />} />
            <Route path='*' element={<NoFound errcode={null} />} />
        </Routes>
    </BrowserRouter>
);

可以粗暴的理解 我的app.js獨挑大樑,他就是一個頁面,而這裡有許多的問題,下個章節會講。


上一篇
Ch2. React從無到有安裝node.js + npm
下一篇
Ch4. NPM插件安裝, React ver.18=>17 有必要退化嗎?
系列文
React前端開發 - 安裝,coding ,架設 - ver. React 17以下14
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言