You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在React同级组件GetSearch与Pexels间传递输入数据?

解决React兄弟组件间的状态传递问题

看起来你遇到了React组件间通信的典型问题——两个独立组件需要共享状态。在React中,对于兄弟组件(没有直接父子关系),最常用的解决方案是状态提升:把需要共享的状态移动到它们的共同父组件中,然后通过props将状态和更新方法传递给子组件。

下面是具体的修改方案,一步步帮你实现需求:

1. 创建共同的父组件(比如App)

我们需要一个父组件来管理搜索关键词的状态,作为GetSearch和Pexels之间的桥梁。

import React from "react";
import GetSearch from "./GetSearch";
import Pexels from "./Pexels";

class App extends React.Component {
  constructor(props) {
    super(props);
    // 父组件维护搜索关键词状态
    this.state = { searchQuery: "" };
    this.handleSearchChange = this.handleSearchChange.bind(this);
    this.handleSearchSubmit = this.handleSearchSubmit.bind(this);
  }

  // 更新搜索关键词的方法,传递给GetSearch组件
  handleSearchChange(newValue) {
    this.setState({ searchQuery: newValue });
  }

  // 处理表单提交的方法,传递给GetSearch组件
  handleSearchSubmit(event) {
    event.preventDefault();
    console.log("开始搜索:", this.state.searchQuery);
    // 如果需要提交时才触发搜索,也可以在这里调用Pexels的搜索方法(不过我们用组件生命周期自动处理更优雅)
  }

  render() {
    return (
      <div>
        {/* 把状态和回调方法传给GetSearch */}
        <GetSearch
          value={this.state.searchQuery}
          onChange={this.handleSearchChange}
          onSubmit={this.handleSearchSubmit}
        />
        {/* 把搜索关键词传给Pexels作为查询参数 */}
        <Pexels query={this.state.searchQuery} />
      </div>
    );
  }
}

export default App;

2. 改造GetSearch组件

去掉GetSearch内部的状态,改为通过props接收父组件传递的状态和更新方法:

import React from "react";

class GetSearch extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    // 调用父组件的方法更新状态
    this.props.onChange(event.target.value);
  }

  handleSubmit(event) {
    // 调用父组件的提交处理方法
    this.props.onSubmit(event);
  }

  render() {
    return (
      {/* 别忘了给form绑定submit事件 */}
      <form className="search-form" onSubmit={this.handleSubmit}>
        <input
          type="text"
          placeholder="Search for images"
          value={this.props.value}
          onChange={this.handleChange}
        />
        <input type="submit" />
      </form>
    );
  }
}

export default GetSearch;

3. 改造Pexels组件

让Pexels通过props接收查询关键词,并在关键词变化时自动调用API:

import React, { Component } from 'react'

export default class Pexels extends Component {
  componentDidMount(){
    // 组件挂载时执行第一次搜索
    this.fetchImages(this.props.query);
  }

  componentDidUpdate(prevProps){
    // 只有当查询关键词变化时,才重新请求API
    if(prevProps.query !== this.props.query){
      this.fetchImages(this.props.query);
    }
  }

  // 封装API请求逻辑,复用性更强
  fetchImages(query){
    // 如果关键词为空,不发起请求
    if(!query.trim()) return;
    
    // 用encodeURIComponent处理关键词,避免特殊字符导致URL错误
    const url = `https://api.pexels.com/v1/search?query=${encodeURIComponent(query)}&per_page=15&page=1`
    const api_key = "xxxxxxxxxxxx"
    
    fetch(url, {
      method: 'GET',
      headers: new Headers({
        'Authorization': api_key
      })
    })
    .then(response => response.json())
    .then(data => {
      console.log(data);
      // 这里可以把获取到的图片数据存在组件状态里,后续用来渲染图片列表
      // this.setState({ images: data.photos });
    })
    .catch(error => console.error(error))
  }

  render() {
    // 后续可以在这里渲染图片列表,比如:
    // const { images } = this.state;
    // return images ? <div>{images.map(img => <img key={img.id} src={img.src.small} />)}</div> : <h1>Hello</h1>
    return ( <h1>Hello</h1>)
  }
}

关键说明

  • 状态提升:这是React中处理组件间共享状态的核心模式,把共享状态放到最近的共同父组件中,子组件通过props交互。
  • 避免不必要的API请求:在componentDidUpdate中判断关键词是否变化,防止每次组件更新都发起请求。
  • URL编码:用encodeURIComponent处理查询关键词,确保特殊字符(比如空格、中文)不会破坏URL结构。

这样修改后,当你在GetSearch的输入框中输入内容,父组件的状态会更新,Pexels组件会自动接收到新的查询关键词并调用API获取对应的数据。

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

火山引擎 最新活动