【问题标题】:React : Add backend filter to fetched dataReact:将后端过滤器添加到获取的数据
【发布时间】:2021-03-23 08:42:42
【问题描述】:

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

我想为获取的元素添加一个额外的过滤器。该过滤器已经在 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;

【问题讨论】:

    标签: javascript reactjs laravel


    【解决方案1】:

    你已经很接近它了。

    只要&lt;input&gt; 字段更改,您当前的实现就会生成搜索url。如果您需要其他过滤器,则需要在实际生成 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)} />
          );
        }
    }
    
    

    【讨论】:

    • 非常感谢。尽管我了解您的代码背后的逻辑,但输入似乎不起作用。我试图将它们包装在 &lt;form&gt; 中,但没有这样做,有什么想法吗?
    • 我还向fetchPatients(key) 添加了密钥,因为密钥未被识别。
    • 其实console.log(response);返回的是一个空数组。
    • Woups,确实,我忘了用fetch(url) 替换fetch。我不能真正测试我在这里写的代码,所以你需要在这里和那里调整一些东西。这为您提供了它背后的基本想法:) 我希望这会有所帮助
    • 我明白了。那么仍然是空数组。我尝试在 onChange 中设置fetchPatients,它与以前的url 一起使用,您提供的新设置似乎由于某种原因不起作用。
    【解决方案2】:

    check this example from pingcrm(使用 laravel、inertiajs 和 vue 构建),特别是在使用 lodash/pickBy 转换替换请求 URL 时

    form: {
      handler: throttle(function() {
        let query = pickBy(this.form)
        this.$inertia.replace(this.route('contacts', Object.keys(query).length ? query : { remember: 'forget' }))
      }, 150),
      deep: true,
    },

    希望帮助。

    【讨论】:

    猜你喜欢
    • 2019-12-23
    • 2013-05-14
    • 1970-01-01
    • 2020-07-10
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多