首页 > 解决方案 > React:将后端过滤器添加到获取的数据

问题描述

我有以下组件,我从表中获取数据,显示它们并能够执行搜索。

我想为获取的元素添加一个额外的过滤器。过滤器已经编码并在 Laravel 中工作,如下所示:

   public function search(Request $request){
        $search = $request ->get('q');
        $Patient = Patient::where('name','Like','%'.$search.'%');

        if ($request->has('gender')) {
            $Patient->where('gender', $request->gender);
        }
        return $Patient->get();
    }

正如您在控制器中看到的,您可以执行搜索和过滤。所以直接访问它的一个例子是:

http://localhost:8000/api/patients/search?q=John&gender=male

现在我能够显示数据并在反应中搜索它,但我不知道如何向链接添加额外的过滤器以从中获取。怎么做?

零件 :

  class Patient extends React.Component {
        constructor(props) {
            super(props)          
            
            this.state = {
                patients : [],
            };
    
            this.handleSearchChange = this.handleSearchChange.bind(this);
        }

  handleSearchChange(key){   
        console.log(key);       
        fetch('http://localhost:8000/api/patients/search?q='+key)
        .then(response => response.json())
        .then(response => {
          this.setState({
            patients: response})
            console.log(response);
        })     
        .catch(err => console.log(err));
      } 
      
          
            componentDidMount() {
                axios.get('api/patients')
                .then(response => {
                  this.setState({
                    patients: response.data})
                })
                .catch(err => console.log(err));                
            }
    
            render() {
            return (
              <div>
                <Container>
                  <div>
                      <input
                        type="text"
                        className="form-control"
                        placeholder="Search..."
                        onChange={e => this.handleSearchChange(e.target.value)}
                      /> 

    <div class="dropdown">
      <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Dropdown button

      </button>
      <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
        <a class="dropdown-item" href="#">Male</a>
        <a class="dropdown-item" href="#">Female</a>
      </div>
    </div>
                  </div>
        
                  <Table>
                    <Thead>
                      <Tr>
                        <Th>ID</Th>
                        <Th>FIRST NAME</Th>
                        <Th>LAST NAME</Th>
                      </Tr>
                    </Thead>
        
                    <Tbody>
        
                      {this.state.patients.reverse().map((patient) => (
                        <Tr>
                          <Td>
                            {patient.id}
                          </Td>
                          <Td>
                            {patient.firstname}
                          </Td>
                          <Td>
                            {patient.lastname}
                          </Td>
                        </Tr>
                      ))}
        
                    </Tbody>
        
                  </Table>
                </Container>
              </div>
            );
          }
        }
        
        export default Patient;

标签: javascriptreactjslaravel

解决方案


你离它很近。

您当前的实现会在字段更改url后立即生成搜索。<input>如果您需要其他过滤器,则需要在实际生成 url 和获取数据之前将这些过滤器值存储在一个状态中。

这是要点的样子。


class Patient extends React.Component {

    constructor(props) {
        super(props)          
        this.state = {
           patients : [],
           filters: {q: '', gender: ''} // we add the filter property to the state
        };
        this.updateFilter = this.updateFilter.bind(this);
    }

    // this will fetch the new patients as soon as one of the filter has been updated
    fetchPatients() {
      const searchParams = new URLSearchParams();
      const {q, gender} = this.state.filters
      if (q) {
        searchParams.set('q', q);
      }
      if (gender) {
        searchParams.set('gender', gender);
      }
      const url = `http://localhost:8000/api/patients/search?${searchParams.toString()}`;
      fetch(url)
            .then(response => response.json())
            .then(response => this.setState({patients: response}))
            .catch(err => console.log(err));
    }

    // this will update a single filter
    updateFilter(filter, value) {
      const currentFilters = this.state.filters;
      this.setState({filters: {...currentFilters, [filter]: value}});
      this.fetchPatients()
    } 

    render() {
      return (
        /*...*/
        <input type="text" onChange={ev => this.updateFilter('q', ev.target.value)} />
        /*...*/
        <input type="text" onChange={ev => this.updateFilter('gender', ev.target.value)} />
      );
    }
}


推荐阅读