You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS实现回车键触发搜索按钮功能问题咨询

解决React中表单回车刷新页面,触发搜索按钮操作的问题

我来帮你搞定这个问题!你现在遇到的情况是:在搜索框按下回车键时,页面会直接刷新,而不是执行和点击搜索按钮一样的图片搜索操作,而且表单和搜索按钮还是两个独立的组件。下面是具体的解决方案,我们按照React的最佳实践来调整代码:

核心思路

  • 首先要阻止表单的默认提交行为,避免浏览器自动刷新页面
  • 把搜索逻辑统一放到父组件(App)中,这样表单提交和按钮点击都能调用同一个搜索方法,更符合React单向数据流的原则
  • 子组件(Button2)只负责渲染按钮和加载状态,触发父组件的搜索方法就好

具体修改步骤

1. 调整父组件(App.js)

我们需要把Button2里的搜索逻辑移到App组件中,给表单添加提交事件,并绑定搜索方法:

import React, { Component } from 'react';
import './App.css';
import { FormGroup, FormControl, InputGroup, Form, } from 'react-bootstrap'
import Conditional from './conditional'
import Button2 from './button.js'
const $ = require('cheerio'); // 统一移到顶部引入

class App extends Component{
  constructor(props){
    super(props)
    this.state = {
      isLoading: true,
      isLoading2: true,
      query: '',
      fimg: [],
    }
    this.isloaded = this.isLoaded.bind(this)
    this.handleSearch = this.handleSearch.bind(this) // 绑定搜索方法
  }

  isLoaded = () => {
    this.setState({
      isLoading: !this.state.isLoading,
      isLoading2: false
    })
  }

  fimgSet = fimgData => {
    this.setState({ fimg: fimgData });
  }

  // 新增搜索方法,原Button2里的搜索逻辑移到这里
  handleSearch(){
    this.isLoaded();
    const BASE_URL = 'https://cors-anywhere.herokuapp.com/https://www.zerochan.net/'
    const DYM_URL = `${BASE_URL}${this.state.query}?s=fav`

    let headers = new Headers({
      'Accept' : "text/plain",
      'Content-Type': "text/plain",
      'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Mobile Safari/537.36'
    });

    fetch(DYM_URL, {
      method: "GET",
      mode: "cors",
      cache: "no-cache",
      credentials: 'same-origin',
      headers: headers, // 修正原代码的笔误:header改为headers
    })
    .then(res => res.text())
    .then(body => {
      const imgUrls = [];
      const imgLen = $('p > a', body).length;
      for (let i = 0; i < imgLen; i++){
        imgUrls[i]=($('p > a', body)[i].attribs.href);
      }
      const regex = /https:\/\/static.zerochan.net.+.(jpg|png)/
      const match = imgUrls.filter(value => regex.test(value));
      this.fimgSet(match);
      this.isLoaded();
    })
    .catch(function(err){
      console.log(err);
      this.isLoaded(); // 出错后也要恢复加载状态,避免一直显示loading
    }.bind(this));
  }

  render(){
    return(
      <div className="App">
        <div className="App-title">
          <span className="bg-title"> Anime Image Gallery </span></div>
        <div className="app-mini-title">
          <span className="bg-title">Enter the name of an Anime series</span></div>
        {/* 给表单添加onSubmit事件,阻止默认刷新并触发搜索 */}
        <Form className="OutterformSize" onSubmit={(e) => {
          e.preventDefault(); // 关键:阻止表单默认提交行为,避免页面刷新
          this.handleSearch(); // 执行搜索逻辑
        }}>
          <FormGroup>
            <InputGroup className="formSize">
              <FormControl size="lg" type="text" placeholder="Try Searching Pokémon, DRAGON+BALL or Wallpaper"
                value = {this.state.query}
                onChange= {event => {this.setState({query: event.target.value})}}
              />
            </InputGroup>
          </FormGroup>
          {/* 把搜索方法传递给Button2组件 */}
          <Button2 
            isLoading={this.state.isLoading} 
            isLoaded={this.isLoaded} 
            onSearch={this.handleSearch}
          />
        </Form>
        <div>
          <Conditional images={this.state.fimg} isLoading2={this.state.isLoading2}/>
        </div>
      </div>
    )
  }
}
export default App;

2. 简化子组件(Button2.js)

现在Button2不需要处理搜索逻辑了,只负责渲染按钮和加载状态,点击时调用父组件传过来的方法:

import React from "react";
import Spinner from 'react-bootstrap/Spinner';
import { ButtonToolbar } from "react-bootstrap";
import Button from 'react-bootstrap/Button'

class Button2 extends React.Component{
  render(){
    if (this.props.isLoading === false){
      return(
        <div>
          <ButtonToolbar className="text-center d-block">
            <Button variant="primary">
              <Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" />
              Loading
            </Button>
          </ButtonToolbar>
        </div>
      )} else {
        return(
          <div>
            <ButtonToolbar className="text-center d-block">
              {/* 点击按钮调用父组件的搜索方法 */}
              <Button variant="primary" type="submit" onClick={() => this.props.onSearch()}>Search</Button>
            </ButtonToolbar>
          </div>
        )}
  }
}
export default Button2;

为什么要这么改?

  • 阻止默认行为:表单默认的提交行为会导致页面刷新,用e.preventDefault()就能直接避免这个问题
  • 统一逻辑:把搜索逻辑放到父组件,让表单和按钮共享同一个方法,不仅符合React的设计理念,也方便后续维护和修改
  • 松耦合:子组件只负责UI,不处理业务逻辑,这样组件之间的依赖更少,更灵活

修改完成后,不管是点击搜索按钮,还是在输入框按下回车键,都会执行图片搜索操作,页面也不会再刷新啦!

内容的提问来源于stack exchange,提问作者VickTree

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:38:32