react 状态提升实现Demo

react 状态提升实现Demo

<!DOCTYPE html>

<head>
  <title>react demo</title>
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

    <!-- Don't use this in production: -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>

<body>
  <script type="text/babel">
    const data = [
      { category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football" },
      { category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball" },
      { category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball" },
      { category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch" },
      { category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5" },
      { category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7" }
    ];

    class FilterableProductTable extends React.Component {
      constructor(props) {
        super(props);
        this.state = { productlist: this.toMap(data), searchText: '', showFlag: false };
      }

      toMap(dataList) {
        let productObj = {}
        dataList.map((value, index) => {
          let p = productObj[value.category]
          if (p != null) {
            productObj[value.category].push(value)
          } else {
            productObj[value.category] = [value]
          }
        })
        return productObj
      }

      search = (e) => {
        this.setState({ searchText: e.target.value });
        this.upDateProductList({ "type": "search", value: e.target.value })
      }

      showStocked = () => {

        const { showFlag } = this.state
        this.setState({ showFlag: !showFlag });
        this.upDateProductList({ "type": "flag", value: !showFlag })
      }

      upDateProductList(mutilObj) {
        let { searchText, showFlag } = this.state
        if (mutilObj['type'] == "search") {
          searchText = mutilObj['value']
        }

        if (mutilObj['type'] == "flag") {
          showFlag = mutilObj['value']
        }

        let tempList = []

        data.map((p, index) => {
          if (p.name.includes(searchText)) {
            // tempList.push(p)
            if (showFlag) {
              if (p.stocked) {
                tempList.push(p)
              }
            } else {
              tempList.push(p)
            }


          }
        })

        this.setState({ productlist: this.toMap(tempList) })
      }

      render() {
        const { productlist, searchText, showFlag } = this.state
        return (
          <div>
            <SearchBar onSearch={this.search} onShowStocked={this.showStocked} value={searchText} flag={showFlag} />
            <ProductTable productlist={productlist} value={showFlag} />
          </div>
        );
      }
    }

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

        this.state = {};

      }

      render() {
        return (
          <div>
            <input type="search" placeholder="Search..." onChange={this.props.onSearch} value={this.props.searchText} /><br></br>
            <input readOnly type="radio" id="btn1" checked={this.props.flag} onClick={this.props.onShowStocked} /><label htmlFor="btn1">Only show products in stock</label>
          </div>
        );
      }
    }

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

        this.state = {};
        // this.productlist = new Map()

      }

      render() {

        const { productlist } = this.props

        let category = []
        for (const key in productlist) {
          category.push(key)
        }

        const pTable = category.map((value, index) => {
          return (
            <tr key={index.toString()}><td><ProductCategoryTable category={value} products={productlist[value]} /></td></tr>
          )
        })

        return (
          <div>
            <table>
              <thead>
                <tr>
                  <td>Name</td>
                  <td>Price</td>
                </tr>
              </thead>
              <tbody>
                {pTable}
              </tbody>
            </table>
          </div>
        );
      }
    }

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

        this.state = {};

      }

      render() {
        const { category, products } = this.props
        const productTable = products.map((value, index) => {
          return (
            <tr key={index.toString()}>
              <td style={{ color: !value.stocked ? 'red' : 'black' }}>{value.name}</td>
              <td>{value.price}</td>
            </tr>
          )
        })
        return (
          <table>
            <thead>
              <tr>
                <td>{category}</td>
              </tr>
            </thead>
            <tbody>
              {productTable}
            </tbody>
          </table>
        );
      }
    }

    const root = ReactDOM.createRoot(document.getElementById('root'))
    root.render(<FilterableProductTable />)

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

</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值