反应状态元素的条件子集

时间:2018-10-07 12:33:33

标签: javascript reactjs

我有一组来自api的结果,它们以状态“结果”存储在状态中。 我想要状态中的第二个数组“ visible_results”。这应该是“结果”的子集。我正在尝试这样做:

export default class SearchScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      results: null,
      visible_results: null,
      low_price: null,
      high_price: null,
      min_price: null,
      max_price: null
    };
  }
  componentDidMount() {
    const apiUrl = 'foo';
    fetch(apiUrl)
      .then(response => response.json())
      .then(response => {
        this.setState({
          results: response.results,
          min_price: 1,
          max_price: 100
        });
        this.setState({
          low_price: this.state.min_price,
          high_price: this.state.max_price
        });
      });
  }

  handleChange = event => {
    const { name, value } = event.target;
    this.setState({
      [name]: +value
    });
    this.setState({
      visible_results: this.state.results.reduce((items, x) => {
        if (this.state.low_price <= x.price && x.price <= this.state.high_price)
          items.push(x);
        return items;
      })
    });
  };

handleChange与两个滑块相关,一个滑块设置low_price,另一个滑块设置high_price。然后,函数应该根据low_price或high_price的新值生成results的子集,并将其保存为状态visible_results。 没用没有错误,但是visible_results始终为“ null”。滑块肯定可以工作。我尝试用if (1==1)替换if语句,以确保它不仅仅是if语句的错字。它做同样的事情。

1 个答案:

答案 0 :(得分:0)

几件事:

  1. 将值设置为null会使您的代码更复杂,我可以添加一个有用的默认值,例如min_price: 0, max_price: Infinity或只是不初始化它。

  2. this.setState是异步的!如果您拨打两次setState,则第一个通话将被推迟,因此第二次通话中this.state尚未更新,例如this.state.low_price中第二个通话中的handleChange尚未更新。

  3. 如果不将初始值传递给reduce,它将采用数组的第一个元素(在您的情况下是一个对象),对此调用push无效。您可能想要.reduce(fn, []),但实际上.filter更合适。

  4. visible_results不必是状态的一部分,因为它是由其他状态道具确定的,因此只需在render

  5. 上确定即可

代码:

export default class SearchScreen extends Component {
 constructor(props) {
   super(props);
   this.state = {
     results: [],
     low_price: 0,
     high_price: Infinity,  
     min_price: 0,
     max_price: Infinity
  };
 }

 componentDidMount() {
   const apiUrl = 'foo';
   fetch(apiUrl)
     .then(response => response.json())
     .then(response => {
       this.setState({
         results: response.results,
         min_price: 1,
         max_price: 100,
         min_price: 1,
         high_price: 100,
      });
    });
  }

  handleChange = event => {
    const { name, value } = event.target;
    this.setState({
      [name]: +value
    });
  }

  render() {
   const { results, low_price, high_price } = this.state;

   const visibleResults = results.filter(item =>
      low_price <= item.price && item.price <= high_price);

     //...
  }
}