React项目状态提升失败:TypeError: props.onSaveStudioData不是函数
问题:React状态提升实现中表单提交报错「props.onSaveStudioData is not a function」
问题描述
学习React状态管理的「状态提升」时,实现表单提交工作室数据到App组件的功能,遇到报错:Form.jsx:58 Uncaught TypeError: props.onSaveStudioData is not a function,导致数据无法传递,始终卡在该错误。
已尝试的排查操作
- 检查NewStudio和App组件的拼写,确认无错误
- 将Form组件的单一状态拆分为多个状态,问题仍未解决
- 将Form组件参数改为props,引发其他错误
组件代码
Form.jsx
export default function Form( props ) { const manilaCities = ["Bulacan", "Caloocan", "Navotas", "Pasig", "Parañaque", "Quezon City", "San Juan", "Taguig"]; const [inputtedTitle, setTitle] = useState('') const [inputtedAddress, setAddress] = useState('') const [inputtedCity, setCity] = useState('') const titleChangeHandler = (event) => { setTitle(event.target.value); }; const addressChangeHandler = (event) => { setAddress(event.target.value); } const cityChangeHandler = (event) => { setCity(event.target.value); }; const submitText = (event) => { event.preventDefault(); const studioData = { name: inputtedTitle, address: inputtedAddress, city: inputtedCity } props.onSaveStudioData(studioData); setTitle(''); setAddress(''); setCity(''); } const cityOption = manilaCities.map((city, index) => <option key={index} value={city}> {city} </option>) return ( <div> <form onSubmit={submitText} className={`bg-sky-500 flex flex-col p-8 m-12 text-center rounded-2xl ${props.isVisible ? "" : "hidden"} `}> <label htmlFor="">Studio Name</label> <input type="text" name="studio-name" value={inputtedTitle} onChange={titleChangeHandler} /> <label htmlFor="">Address </label> <input type="text" name="Hey" value={inputtedAddress} onChange={addressChangeHandler} /> <label htmlFor=""> City </label> <select value={inputtedCity} onChange={cityChangeHandler} > {cityOption} </select> <label htmlFor=""> Studio Image </label> <span className="m-1"><input type="file" name="Hey" id="" /></span> <span className="inline-block"><button type="submit" className="rounded-full bg-sky-50 py-2 px-4 m-1">Add Studio</button></span> </form> </div> ); }
NewStudio.jsx
import Form from '../Form'; export default function NewStudio(props) { const saveStudioDataHandler = (enteredStudioData) => { const studioData = { ...enteredStudioData, id: Math.random().toString() }; props.onAddStudio(studioData); } return ( <div> <Form onSaveStudioData = {saveStudioDataHandler} /> </div> ) }
App.jsx
import Form from './components/Form'; import StudioList from './components/Studios/StudioList' import { useState } from 'react'; import NewStudio from './components/Studios/NewStudio'; export default function App() { const [isFormVisible, setIsFormVisible] = useState(false); const toggleFormVisibility = () => { setIsFormVisible(!isFormVisible); } const addStudioHandler = (studio) => { console.log('In App.js') console.log(studio); } return ( <div> <Nav toggleForm={toggleFormVisibility}/> <NewStudio onAddStudio={addStudioHandler}/> <Hero/> <Form isVisible={isFormVisible} /> <StudioList/> </div> ) }
解决方案
问题根源是App组件中重复渲染了两个Form实例:
- 一个通过NewStudio组件渲染,带有
onSaveStudioData回调函数 - 另一个直接在App中渲染,仅传入了
isVisible属性,未传递onSaveStudioData
当用户操作的是第二个Form实例时,提交表单就会触发props.onSaveStudioData,但该属性不存在,因此抛出类型错误。
修复步骤:
- 删除App组件中直接渲染的
<Form isVisible={isFormVisible} /> - 将
isVisible状态传递给NewStudio组件,再由NewStudio转发给Form
修改后的代码:
修改App.jsx的return部分
return ( <div> <Nav toggleForm={toggleFormVisibility}/> <NewStudio onAddStudio={addStudioHandler} isVisible={isFormVisible}/> <Hero/> <StudioList/> </div> )
修改NewStudio.jsx
import Form from '../Form'; export default function NewStudio(props) { const saveStudioDataHandler = (enteredStudioData) => { const studioData = { ...enteredStudioData, id: Math.random().toString() }; props.onAddStudio(studioData); } return ( <div> <Form onSaveStudioData={saveStudioDataHandler} isVisible={props.isVisible} /> </div> ) }
这样就能确保所有使用的Form实例都具备onSaveStudioData回调,表单提交后数据可以正常通过状态提升传递到App组件。
内容的提问来源于stack exchange,提问作者JR P
相关产品推荐
相关产品推荐

