加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactJs的Lifting State Up

发布时间:2020-12-15 06:40:19 所属栏目:百科 来源:网络整理
导读:Lifting State Up是什么意思? 意思就是可以把子类的state向上传递给它的父类 看下面代码,是从react官方摘抄的 class ProductCategoryRow extends React . Component { render() { const category = this .props.category; return ( tr th colSpan= "2" {ca

Lifting State Up是什么意思? 意思就是可以把子类的state向上传递给它的父类

看下面代码,是从react官方摘抄的

class ProductCategoryRow extends React.Component {
  render() {
    const category = this.props.category;
    return (
      <tr>
        <th colSpan="2">
          {category}
        </th>
      </tr>
    );
  }
}

class ProductRow extends React.Component {
  render() {
    const product = this.props.product;
    const name = product.stocked ?
      product.name :
      <span style={{color: 'red'}}>
        {product.name}
      </span>;

    return (
      <tr>
        <td>{name}</td>
        <td>{product.price}</td>
      </tr>
    );
  }
}

class ProductTable extends React.Component {
  render() {
    const filterText = this.props.filterText;
    const inStockOnly = this.props.inStockOnly;

    const rows = [];
    let lastCategory = null;

    this.props.products.forEach((product) => {
      if (product.name.indexOf(filterText) === -1) {
        return;
      }
      if (inStockOnly && !product.stocked) {
        return;
      }
      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>
    );
  }
}

class SearchBar extends React.Component {
  constructor(props) {
    super(props);
    this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
    this.handleInStockChange = this.handleInStockChange.bind(this);
  }

  handleFilterTextChange(e) {
    this.props.onFilterTextChange(e.target.value);
  }

  handleInStockChange(e) {
    this.props.onInStockChange(e.target.checked);
  }

  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Search..."
          value={this.props.filterText}
          onChange={this.handleFilterTextChange}
        />
        <p>
          <input
            type="checkbox"
            checked={this.props.inStockOnly}
            onChange={this.handleInStockChange}
          />
          {' '}
          Only show products in stock
        </p>
      </form>
    );
  }
}

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

    this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
    this.handleInStockChange = this.handleInStockChange.bind(this);
  }

  handleFilterTextChange(filterText) {
    this.setState({
      filterText: filterText
    });
  }

  handleInStockChange(inStockOnly) {
    this.setState({
      inStockOnly: inStockOnly
    })
  }

  render() {
    return (
      <div>
        <SearchBar
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
          onFilterTextChange={this.handleFilterTextChange}
          onInStockChange={this.handleInStockChange}
        />
        <ProductTable
          products={this.props.products}
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
        />
      </div>
    );
  }
}


const PRODUCTS = [
  {category: 'Sporting Goods',price: '$49.99',stocked: true,name: 'Football'},{category: 'Sporting Goods',price: '$9.99',name: 'Baseball'},price: '$29.99',stocked: false,name: 'Basketball'},{category: 'Electronics',price: '$99.99',name: 'iPod Touch'},price: '$399.99',name: 'iPhone 5'},price: '$199.99',name: 'Nexus 7'}
];

ReactDOM.render(
  <FilterableProductTable products={PRODUCTS} />,document.getElementById('container')
);

这段代码要实现以下效果:

当在输入框输入一些文字的时候,能够根据输入的文字搜索结果,然后把过滤的结果显示出来,注意没输入一个字都要过滤检查一次。

现在主要看每次输入一个字符,就过滤一次结果怎么实现的?
首先关注FilterableProductTable 类中有如下代码:

<div>
        <SearchBar
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
          onFilterTextChange={this.handleFilterTextChange}
          onInStockChange={this.handleInStockChange}
        />
        <ProductTable
          products={this.props.products}
          filterText={this.state.filterText}
          inStockOnly={this.state.inStockOnly}
        />
      </div>
handleFilterTextChange(filterText) {
    this.setState({
      filterText: filterText
    });
  }

  handleInStockChange(inStockOnly) {
    this.setState({
      inStockOnly: inStockOnly
    })

首先是当SearchBar中输入的文字变化后会调用handleFilterTextChange/handleInStockChange方法,然后把输入的文字作为参数传递进去,然后在handleFilterTextChange/handleInStockChange的方法中调用this.setState更新属性,从而引发渲染操作,并且把新的state传递给ProductTable,ProductTable根据新的属性过滤商品列表,从而把过滤的结果显示出来。

这个是整体的流程。
需要有两个地方注意:
1.

handleFilterTextChange/handleInStockChange是SearchBar的属性,应该属于SearchBar的方法,而且也是被SearchBar触发调用的,但最终实现是在FilterableProductTable
中,而且在方法中用到了this关键字,那么方法中的this指的应该是SearchBar,怎么才能让this指向FilterableProductTable
? 答案就是:

this.handleFilterTextChange = this.handleFilterTextChange.bind(this);
    this.handleInStockChange = this.handleInStockChange.bind(this);

2.
onFilterTextChange函数是怎么被触发的?
首先看SearchBar:

handleFilterTextChange(e) {
    this.props.onFilterTextChange(e.target.value);
  }

  handleInStockChange(e) {
    this.props.onInStockChange(e.target.checked);
  }

  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Search..."
          value={this.props.filterText}
          onChange={this.handleFilterTextChange}
        />
        <p>
          <input
            type="checkbox"
            checked={this.props.inStockOnly}
            onChange={this.handleInStockChange}
          />
          {' '}
          Only show products in stock
        </p>
      </form>
    );

input标签有个onChange属性,当输入的文字变化的时候会触发该方法,然后该方法用调用了handleFilterTextChange
-> this.props.onFilterTextChange(e.target.value),最终调用了它属性里面的onFilterTextChange方法,这个方法是在FilterableProductTable中指定并定义的,所以就调用到了FilterableProductTable中的onFilterTextChange方法,其实就是通过props实现了一个回调函数。

这样最终就实现了,状态的向上传递。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读