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

React中使用useContext传递输入框值失败问题求助

问题:useContext传递输入框值时Home组件无响应

我想通过useContext传递输入框的值,已经创建了context.js,在Menu组件中用menuContext.Provider绑定了输入框的state值,但在Home组件中无法获取该值来筛选产品。手动设置context的默认值能得到结果,但输入内容时无响应,请问哪里出错了?

相关代码

context.js

import {createContext} from 'react'

const menuContext = createContext('')

export {menuContext}

Menu组件

import React , {useState} from 'react'
import { menuContext } from './helper/context'

 const Menu = () => {
    
  const [text, setText] = useState('')  
     
  return (
    <div>     
      <nav className='navbar navbar-dark bd-dark' dir='rtl'>
        <menuContext.Provider value={text}>
          <form className='form-inline'>                       
            <input 
                className="form-control mr-sm-2" 
                type="search" placeholder="جستجوی نام کالا" 
                aria-label="Search"
                onChange={ (event) =>{
                  setText(event.target.value)
                }}                                                                                                                                                                   
            />                    
          </form>   
        </menuContext.Provider>     
      </nav>                   
    </div>
  )
}

export default Menu;

Home组件

import React , {useState, useEffect, useContext} from 'react'
import { getProducts } from './helper/Coreapicalls';
import Base from './Base';
import Card from './Card';
import "../styles.css"
import { menuContext } from './helper/context';


export default function Home () {

  const [products, setProducts] = useState([]);
  const [filteredProducts, setFilteredProducts] = useState([]) 
  const [error, setError] = useState(false);  
  const [searchIsPresent, setSearchIsPresent] = useState(true);  
  const searchInput = useContext(menuContext)      


  const loadAllProducts = () => {
    getProducts()
    .then((data) =>{
      if (data.error){
        setError(data.error);
        console.log(error);
      }
      else{
        setProducts(data);
      }
    })    
  }   

  useEffect(() => {
    loadAllProducts()
  }, []);
  
  function filterItems(arr, query) {
    return arr.filter((el) => el['subbranch3'].toLowerCase().includes(query.toString().toLowerCase()));
  }  
  
  const loadFilteredProducts = () => {
    setFilteredProducts(filterItems(products, searchInput))
    // if (filteredProducts.length !== 0) {
    //   setSearchIsPresent(true)
    // }else{
    //   setSearchIsPresent(false)
    // }    
  }
   
  useEffect ( () => {
    loadFilteredProducts()
  }, [searchInput])  

  const showSearchResult = searchIsPresent =>{
    return(
      searchIsPresent &&
      <div className="row">
         {filteredProducts.map((fProduct, index) =>{
          return(
            <div key={index} className='col-4 mb-4'>
              <Card product={fProduct}/>
            </div>
          )
        })}
      </div>
    )
  }
  
  
  return (
    <Base title='صفحه اصلی' description='به فروشگاه اینترنتی خوش آمدید'>      
      <div>
        {showSearchResult(searchIsPresent)}
      </div>
      <div className="row">
         {products.map((product, index) =>{
          return(
            <div key={index} className='col-4 mb-4'>
              <Card product={product}/>
            </div>
          )
        })}
      </div>
    </Base>
  );
}

问题分析

核心问题是menuContext.Provider的层级错误:你在Menu组件里只把Provider包裹了输入框,而Home组件不在这个Provider的子组件树中,所以Home始终获取的是context的默认值,完全感知不到输入框state的变化。

解决方案

需要把menuContext.Provider提升到足够高的层级,确保Menu(输入框)和Home(消费context)都在Provider的范围内,具体步骤如下:

  1. 修改Menu组件:移除内部的Provider,通过回调把输入值传递给父组件
import React , {useState} from 'react'

const Menu = ({ onSearchChange }) => {
  const [text, setText] = useState('')  

  const handleChange = (event) => {
    const inputValue = event.target.value
    setText(inputValue)
    onSearchChange(inputValue) // 将输入值同步到父组件的状态
  }
     
  return (
    <div>     
      <nav className='navbar navbar-dark bd-dark' dir='rtl'>
        <form className='form-inline'>                       
          <input 
              className="form-control mr-sm-2" 
              type="search" placeholder="جستجوی نام کالا" 
              aria-label="Search"
              onChange={handleChange}                                                                                               
          />                    
        </form>     
      </nav>                   
    </div>
  )
}

export default Menu;
  1. 在根组件(如App.js)中设置Provider:管理全局搜索状态,同时包裹Menu和Home
import React, { useState } from 'react'
import { menuContext } from './helper/context'
import Menu from './Menu'
import Home from './Home'

function App() {
  const [searchText, setSearchText] = useState('')

  return (
    <menuContext.Provider value={searchText}>
      <Menu onSearchChange={setSearchText} />
      <Home />
    </menuContext.Provider>
  )
}

export default App;
  1. 优化Home组件的筛选逻辑(可选):让空输入时显示全部产品,提升体验
const loadFilteredProducts = () => {
  const filtered = filterItems(products, searchInput)
  setFilteredProducts(filtered)
  // 空输入时也显示结果,或者根据需求调整
  setSearchIsPresent(filtered.length > 0 || searchInput === '')
}

现在Home组件就能实时接收到输入框的变化,正常执行产品筛选了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:02:34