简体   繁体   English

如何只单击一次搜索按钮而不是两次即可检索搜索结果?

[英]How can I retrieve search results with only one click of the search button instead of two?

I am working on a Node.js + ElasticSearch + React.js project and I have managed to get the search to work! 我正在开发Node.js + ElasticSearch + React.js项目,并且设法使搜索生效! However, I have to click the search button twice before I get back results in my console. 但是,我必须两次单击搜索按钮才能在控制台中获得结果。 Eventually, I would like to output the results via components to the user. 最终,我想通过组件将结果输出给用户。 any input would be great! 任何输入都会很棒!

Here is 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; 

here is Node.js: 这是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)); 

this.setState() is an asynchronous function, which means that the updated data will only be available in its callback. this.setState()是一个异步函数,这意味着更新的数据将仅在其回调中可用。

To better show this, try with this modification: 为了更好地显示这一点,请尝试以下修改:

 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);       
        });
      })
  }

Note: you are handling your "userText" field as an uncontrolled field. 注意:您正在将“ userText”字段作为不受控制的字段处理。 This means that you let it be filled by native html+js, and just get the content from the DOM. 这意味着您让它由本机html + js填充,并且仅从DOM中获取内容。 Doing this, you never really need to have a "userInput" state variable. 这样,您实际上就不需要拥有“ userInput”状态变量。

Here is a snippet with userText as a controlled field: 这是一个以userText作为受控字段的代码段:

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>
    );
  }
}

I believe you'd better implement onChange function on your input, so you would have actual user search request the moment he or she would type it in. 我相信您最好在输入中实现onChange函数,这样一来,当用户输入搜索请求时,便会收到实际的用户搜索请求。

Take official react doc for this example https://reactjs.org/docs/forms.html 对于此示例, 获取官方的反应文档https://reactjs.org/docs/forms.html

The reason it takes two times for the button to be pushed is that (may be) your state would become familiar with search request only after first push, and then you need second to actually get axios to send request (because it is null on first one) 按下按钮需要两次的原因是(可能是)您的状态仅在第一次按下后才熟悉搜索请求,然后您需要第二次才能真正使axios发送请求(因为首先为null)一)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM