9

我是新手,我正在做一个小项目,该项目使用搜索栏来查找我从数据库中获取的数据。

该组件的代码如下:

import React, { Component } from 'react';

class BodyData extends Component {
    state = {
        query: '',
        data: [],
    }

    handleInputChange = () => {
        this.setState({
            query: this.search.value
        })
        this.filterArray();
    }

    getData = () => {
        fetch(`http://localhost:4000/restaurants`)
        .then(response => response.json())
        .then(responseData => {
            // console.log(responseData)
            this.setState({
                data:responseData
            })
        })
    }

    filterArray = () => {
        var searchString = this.state.query;
        var responseData = this.state.data
        if(searchString.length > 0){
            // console.log(responseData[i].name);
            responseData = responseData.filter(l => {
                console.log( l.name.toLowerCase().match(searchString));
            })
        }
    }

    componentWillMount() {
        this.getData();
    }
    render() {
        return (
            <div className="searchForm">
                <form>
                    <input type="text" id="filter" placeholder="Search for..." ref={input => this.search = input} onChange={this.handleInputChange}/>
                </form>
                <div>
                    {
                        this.state.data.map((i) =>
                            <p>{i.name}</p>
                        )
                    }
                </div>
            </div>
        )
    }
}


export default BodyData;

所以基本上,我想在输入查询文本时更新状态,并减少我映射的餐厅名称,直到找到匹配项。

据我了解,this.state.data将在我在搜索栏中输入查询时进行过滤。但是,当我绘制地图时this.state.data,我得到的是整个餐厅列表,而不是我想看到的。

我已经经历了一堆 tutes,我不完全确定如何去做。

任何人都可以帮我解决这个问题吗?也欢迎对代码提出任何其他意见。我是来学习的:)

谢谢!

4

4 回答 4

7

您可以保留一个名为 eg 的附加状态,其中包含名称中包含您的filteredData所有元素,然后渲染它。dataquery

例子

class BodyData extends React.Component {
  state = {
    query: "",
    data: [],
    filteredData: []
  };

  handleInputChange = event => {
    const query = event.target.value;

    this.setState(prevState => {
      const filteredData = prevState.data.filter(element => {
        return element.name.toLowerCase().includes(query.toLowerCase());
      });

      return {
        query,
        filteredData
      };
    });
  };

  getData = () => {
    fetch(`http://localhost:4000/restaurants`)
      .then(response => response.json())
      .then(data => {
        const { query } = this.state;
        const filteredData = data.filter(element => {
          return element.name.toLowerCase().includes(query.toLowerCase());
        });

        this.setState({
          data,
          filteredData
        });
      });
  };

  componentWillMount() {
    this.getData();
  }

  render() {
    return (
      <div className="searchForm">
        <form>
          <input
            placeholder="Search for..."
            value={this.state.query}
            onChange={this.handleInputChange}
          />
        </form>
        <div>{this.state.filteredData.map(i => <p>{i.name}</p>)}</div>
      </div>
    );
  }
}
于 2018-08-07T12:24:06.967 回答
5

这是适合您的代码

import React, { Component } from 'react';

class BodyData extends Component {

state = {
    query: '',
    data: [],
    searchString:[]
}

handleInputChange = (event) => {
    this.setState({
        query: event.target.value
    },()=>{
  this.filterArray();
})

}

getData = () => {
    fetch(`http://localhost:4000/restaurants`)
    .then(response => response.json())
    .then(responseData => {
        // console.log(responseData)
        this.setState({
            data:responseData,
            searchString:responseData
        })
    })
}

filterArray = () => {
    let searchString = this.state.query;
    let responseData = this.state.data;



    if(searchString.length > 0){
        // console.log(responseData[i].name);
        responseData = responseData.filter(searchString);
this.setState({
   responseData
})
    }

}

componentWillMount() {
    this.getData();
}
render() {
    return (
        <div className="searchForm">
            <form>
                <input type="text" id="filter" placeholder="Search for..."  onChange={this.handleInputChange}/>
            </form>
            <div>
                {
                    this.state.responseData.map((i) =>
                        <p>{i.name}</p>
                    )
                }
            </div>
        </div>
    )
  }
}


export default BodyData;

需要进行的更改很少。

  1. 设置状态是异步工作的。所以,当您需要在设置状态后立即执行某些操作时,避免它使用箭头功能。
  2. es6 中有 2 个不同的关键字而不是 var。常量。使用它们而不是 var。
  3. 输入中不需要 ref。您可以通过 event.target.value 直接获取输入的值

享受编码!

于 2018-08-07T12:42:47.823 回答
0

setState方法是异步的,它有第二个参数 - 应用状态时调用的回调。

你需要改变handleInputChange方法。

handleInputChange = () => {
    this.setState({
        query: this.search.value
    }, this.filterArray)
}
于 2018-08-07T12:15:53.750 回答
0

我想展示几个指针-

  1. setState({})函数是异步的,您必须使用函数setState和调用filteredArray方法作为回调。或者,调用filteredArrayat render,您的值将在此处更新和反映。
  2. 您的filterArray方法没有返回/设置过滤的数据列表。因此,您键入的内容即使被过滤,也不会在任何地方设置/返回。
于 2018-08-07T12:19:56.123 回答