【问题标题】:How can I retrieve search results with only one click of the search button instead of two?如何只单击搜索按钮而不是两次来检索搜索结果?
【发布时间】:2019-07-11 06:52:48
【问题描述】:

我正在开发一个 Node.js + ElasticSearch + React.js 项目,我已经设法让搜索工作了!但是,我必须单击搜索按钮两次才能在控制台中返回结果。最终,我想通过组件将结果输出给用户。任何输入都会很棒!

这里是 React.js:

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {

    state = {
      result: [],
      name: 'Roger',
      userInput: null,
    }


  handleSubmit = event=> {
    event.preventDefault();

    var input = document.getElementById("userText").value;
    this.setState({ userInput: input });
    axios.get('http://localhost:4000/search?query=' + this.state.userInput)
      .then(res => {
        var result = res.data;
        this.setState({ result: result });
        console.log(this.state.result);
        console.log(this.state.userInput);
      })

  }

  render() {
    return (
      <div className="App">
        <h2>hello from react</h2>
          <form action="/search">
            <input type="text" placeholder="Search..." name="query" id="userText"/>
            <button type="submit" onClick={this.handleSubmit}><i>Search</i></button>
          </form>
      </div>
    );
  }
}

export default App;

这里是 Node.js:

const express = require('express');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const JSON = require('circular-json');
const PORT = 4000;
var client = require ('./connection.js');
var argv = require('yargs').argv;
var getJSON = require('get-json');
const cors = require('cors');

let app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use(cors({
  origin: 'http://localhost:3001',
  credentials: true
}));

app.get('/', function(req, res){
  res.send("Node is running brother");
});

app.get("/search", function (request, response) {
  client.search({
    index: 'club',
    type: 'clubinfo',
    body: {
      query: {
        match: { "name": query}
      },
    }
  },function (error, data, status) {
    if (error) {
    return console.log(error);
  }
      else {
        // Send back the response
        response.send(data);
      }
  });
});

app.listen(PORT, () => console.log('wowzers in me trousers, Listening on port ' + PORT));

【问题讨论】:

    标签: node.js reactjs elasticsearch


    【解决方案1】:

    this.setState()是一个异步函数,这意味着更新的数据只会在其回调中可用。

    为了更好地展示这一点,请尝试以下修改:

     handleSubmit = event=> {
        event.preventDefault();
    
        var input = document.getElementById("userText").value;
    
        axios.get('http://localhost:4000/search?query=' + input)
          .then(res => {
            var result = res.data;
            this.setState({ result: result, userInput: input }, () => {
              console.log(this.state.result);
              console.log(this.state.userInput);       
            });
          })
      }
    

    注意:您将“userText”字段作为不受控制的字段处理。这意味着你让它被原生 html+js 填充,并且只从 DOM 中获取内容。这样做,你永远不需要有一个“userInput”状态变量。

    这是一个带有userText 作为受控字段的sn-p:

    class App extends Component {
    
        state = {
          result: [],
          name: 'Roger',
          userInput: '',
        }
    
      handleChange = event=> {
        event.preventDefault();
        this.setState({userInput: event.target.value});
      }
    
      handleSubmit = event=> {
        event.preventDefault();
    
        axios.get('http://localhost:4000/search?query=' + this.state.userInput)
          .then(res => {
            var result = res.data;
            this.setState({ result: result });
            console.log(this.state.result);
            console.log(this.state.userInput);
          })
    
      }
    
      render() {
        return (
          <div className="App">
            <h2>hello from react</h2>
              <form action="/search">
                <input type="text" value={this.state.userInput} onChange={this.handleChange} placeholder="Search..." name="query" id="userText"/>
                <button type="submit" onClick={this.handleSubmit}><i>Search</i></button>
              </form>
          </div>
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      我相信你最好在你的输入上实现 onChange 函数,这样你就会在他或她输入的那一刻得到实际的用户搜索请求。

      以官方反应文档为例 https://reactjs.org/docs/forms.html

      按钮需要两次推送的原因是(可能)您的状态只有在第一次推送后才会熟悉搜索请求,然后您需要第二次才能真正让 axios 发送请求(因为它是第一个为空)

      【讨论】:

        猜你喜欢
        • 2020-02-27
        • 1970-01-01
        • 2020-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多