React项目App.js调用组件时出现searchTerm等变量未定义编译错误如何解决
问题根因
你把searchTerm状态、handleSearch回调、searchedStories过滤逻辑、stories源数据全部定义在了子组件InputWithLabel的内部作用域,父组件App无法直接访问子组件内部变量,所以引用这三个变量时会报未定义错误。
修复方案
采用状态提升的写法,把和业务逻辑相关的状态、数据、处理函数都放到父组件App中定义,子组件仅保留输入框聚焦、渲染标签和输入框的通用逻辑即可。
修改后的App.js代码
import React, { useState, useEffect } from 'react'; import './App.css'; import Greeting from '../Greeting/Greeting'; import InputWithLabel from '../Search/Search'; import List from '../List/List'; // 自定义持久化钩子移到父组件 const useSemiPersistentState = (key, initialState) => { const [value, setValue] = useState( localStorage.getItem(key) || initialState ); useEffect(() => { localStorage.setItem(key, value); }, [value, key]); return [value, setValue] }; // 模拟数据源也移到父组件 const stories = [ { title: 'React', url: 'https://reactjs.org/', author: 'Jordan Walke', num_comments: 3, points: 4, objectID: 0, }, { title: 'Redux', url: 'https://redux.js.org/', author: 'Dan Abramov, Andrew Clark', num_comments: 2, points: 5, objectID: 1, }, ]; // App component const App = () => { // 搜索状态定义在父组件 const [searchTerm, setSearchTerm] = useSemiPersistentState( 'search', 'React' ); // 搜索回调定义在父组件 const handleSearch = (event) => { setSearchTerm(event.target.value); }; // 过滤逻辑定义在父组件 const searchedStories = stories.filter((story) => story.title.toLowerCase().includes(searchTerm.toLowerCase()) ); return ( <div className="App"> <InputWithLabel id="search" value={searchTerm} isFocused onInputChange={handleSearch} > <strong>Search:</strong> </InputWithLabel> <hr /> <List list={searchedStories} /> </div> ); } export default App;
修改后的Search.js代码
import React, { useRef, useEffect } from 'react'; // Search bar仅保留通用输入逻辑 function InputWithLabel({ id, value, type = "text", onInputChange, isFocused, children, }) { const inputRef = useRef(); useEffect(() => { if (isFocused && inputRef.current) { inputRef.current.focus(); } }, [isFocused]); return ( <> <label htmlFor={id}>{children}</label> <input ref={inputRef} id={id} type={type} value={value} autoFocus={isFocused} onChange={onInputChange} /> </> ) } export default InputWithLabel;
核心改动说明
- 把和业务绑定的数据源、状态、处理逻辑全部提升到父组件,子组件只做通用UI组件的功能,职责更清晰
- 父组件把需要的值和回调通过props传递给子组件,子组件触发回调更新父组件状态,符合React单向数据流的设计原则
内容的提问来源于stack exchange,提问作者Halp_am_stuck
相关产品推荐
相关产品推荐

