iT邦幫忙

1

React 學習筆記_7 (Thinking in React - 3 )

第三步:找出最少(但完整)的 UI State

  • 思考應用程式最少需要哪些可變的 state,關鍵是DRY(避免重複代碼原則)
    DRY(避免重複代碼原則):在軟體開發中,減少重複的資訊,簡單來說就是不要寫重複的程式,可以把共同的程式取出來統一放到一個地方進行呼叫而不是相同的程式寫很多次。
  • 須注意與思考的三個點:
    1.這個資料是從父層透過 props 傳下來的嗎?如果是的話,那它很可能不是 state。
    2.這個資料是否一直保持不變呢?如果是的話,那它很可能不是 state。
    3.是否可以根據 component 中其他的 state 或 prop 來計算這個資料呢?如果是的話,那它一定不是 state。
    商品數據庫是被當作 prop 往下傳的,所以它不是 state。而搜尋關鍵字和 checkbox會隨時間而改變,也不能從其他東西中被計算出來,所以是state。

第四步:找出你的 State 應該在哪裡

  • 指出每個根據 state 來 render 某些東西的 component。
  • 找出一個共同擁有者 component(在層級中單一一個需要 state 的、在所有的 component 之上的 component)。
  • 應該擁有 state 的會是共同擁有者 component 或另一個更高層級的 component。
  • 如果你找不出一個應該擁有 state 的 component 的話,那就建立一個新的 component 來保持 state,並把它加到層級中共同擁有者 component 之上的某處。
  1. ProductTable 需要根據 state 來篩選產品列表,而 SearchBar 需要展示搜尋關鍵字和 checkbox 的 state。
  2. 這兩個 component 的共同擁有者 component 是 FilterableProductTable。
  • FilterableProductTable
    • SearchBar (搜尋關鍵字和 checkbox)
    • ProductTable (篩選產品列表)
      • ProductCategoryRow
      • ProductRow

流程圖 :
https://ithelp.ithome.com.tw/upload/images/20200321/20124767Zy9lenatKh.png

FilterableProductTable:
放置State的初始化,並將state透過props傳遞給子層(SearchBar / ProductTable)

class FilterableProductTable extends React.Component 
{
    constructor(props) 
    {
      super(props);
      //state初始化
      this.state = {
        filterText: '',
        inStockOnly: false
      };
    }

    render() 
    {
      return (
        <div>
          {/* 將初始化的state利用props傳遞給Sub Component */}
         <SearchBar
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
        />
        <ProductTable
          products={this.props.products}
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
        />
        </div>
      );
    }
}

SearchBar :
接收父層的數據庫資料與state,並將牠放入html中

class SearchBar extends React.Component 
  {
    render() 
    {
      const filterText = this.props.filterText;
      const inStockOnly = this.props.inStockOnly;
  
      return (
        <form>
          {/* 將父層傳遞的State放入HTML元件中,設定初始狀態 */}
          <input
            type="text"
            placeholder="Search..."
            value={filterText} />
          <p>
            <input
              type="checkbox"
              checked={inStockOnly} />
            {' '}
            Only show products in stock
          </p>
        </form>
      );
    }
  }

ProductTable:
接收父層的數據庫資料與state,並加入與html之間互動的判斷(表單填入資料與數據庫比對、checkedBox和庫存狀態)

class ProductTable extends React.Component 
  {
    render() 
    {
      const filterText = this.props.filterText;
      const inStockOnly = this.props.inStockOnly;
  
      const rows = [];
      let lastCategory = null;
  
      /*
        將數據庫陣列內每個元素傳入function
        function判斷:
                      1.判斷輸入表單的name是否是數據庫中的name,若不是(-1)則跳出function
                      2.判斷checkbox是否有被勾選(true)與是否沒有庫存(!(stocked=true) = false)
                      3.判斷category是否與前一個一樣,若不是的便會將"ProductCategoryRow"加入到row陣列中並把"category" 與  "key"利用props傳給子層;若一樣便會把"ProductRow"加入到row陣列並將"product" 與 "key"利用props傳給子層
      */

      this.props.products.forEach((product) => {
        //indexOf() : 回傳給定元素於陣列中第一個被找到之索引,若不存在於陣列中則回傳-1
        if (product.name.indexOf(filterText) === -1) 
        {
          return;
        }
        else if (inStockOnly && !product.stocked) 
        {
          return;
        }
        else if (product.category !== lastCategory) 
        {
          rows.push(
            <ProductCategoryRow
              category={product.category}
              key={product.category} />
          );
        }
        rows.push(
          <ProductRow
            product={product}
            key={product.name}
          />
        );
        lastCategory = product.category;
      });

      return (
        <table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>{rows}</tbody>
        </table>
      );
    }
  }

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

尚未有邦友留言

立即登入留言