React箭头函数组件中react-select选择时报TypeError求助
问题描述
在React箭头函数组件开发中,尝试将原有<input>字段替换为react-select组件,使用包含17个SDG选项的SDGOptions数组作为下拉选项:
// 存储17个SDG选项的数组 export const SDGOptions = [ { value: '', label: 'Any'}, { value: 'SDG 1: No Poverty', label: 'SDG 1: No Poverty'}, { value: 'SDG 2: Zero Hunger', label: 'SDG 2: Zero Hunger'}, { value: 'SDG 3: Good Health & Well Being', label: 'SDG 3: Good Health & Well Being'}, { value: 'SDG 4: Quality Education', label: 'SDG 4: Quality Education'}, { value: 'SDG 5: Gender Equality', label: 'SDG 5: Gender Equality'}, { value: 'SDG 6: Clean Water & Sanitation', label: 'SDG 6: Clean Water & Sanitation'}, { value: 'SDG 7: Affordable & Clean Energy', label: 'SDG 7: Affordable & Clean Energy'}, { value: 'SDG 8: Decent Work & Economic Growth', label: 'SDG 8: Decent Work & Economic Growth'}, { value: 'SDG 9: Industry, Innovation, & Infrastructure', label: 'SDG 9: Industry, Innovation, & Infrastructure'}, { value: 'SDG 10: Reduced Inequalities', label: 'SDG 10: Reduced Inequalities'}, { value: 'SDG 11: Sustainable Cities & Communities', label: 'SDG 11: Sustainable Cities & Communities'}, { value: 'SDG 12: Responsible Consumption & Production', label: 'SDG 12: Responsible Consumption & Production'}, { value: 'SDG 13: Climate Action', label: 'SDG 13: Climate Action'}, { value: 'SDG 14: Life Below Water', label: 'SDG 14: Life Below Water'}, { value: 'SDG 15: Life On Land', label: 'SDG 15: Life On Land'}, { value: 'SDG 16: Peace, Justice, & Strong Institutions', label: 'SDG 16: Peace, Justice, & Strong Institutions'}, { value: 'SDG 17: Partnerships for the Goals', label: 'SDG 17: Partnerships for the Goals'}, ]
下拉列表可正常展开,但点击选择选项时出现报错:
Uncaught TypeError: Cannot read properties of undefined (reading 'value') at onChange (ProjectAdminForm.js:92:1)
组件代码如下:
import { useState } from "react"; import { SDGOptions } from "../FilterComponents/CategoryArrays/SdgOptions"; import Multiselect from "multiselect-react-dropdown" import Select from 'react-select'; const ProjectAdminForm = () => { const [sdg, setSDG] = useState('') const handleSubmit = async (e) => { e.preventDefault() console.log('button clicked') const project = {sdg} console.log(project) const response = await fetch('/api/projects', { method: 'POST', body: JSON.stringify(project), headers: { 'Content-Type': 'application/json' } }) const json = await response.json if (!response.ok) { setError(json.error) } if (response.ok) { setSDG('') alert('Project added!') console.log('new project added', json) } } return ( <form className="create project-form" onSubmit={handleSubmit}> <h2 style={{"textAlign": "center"}}>Add a New Project</h2> <hr></hr> <label>Sustainable Development Goal:</label> <Select className="basic-single" classNamePrefix="select" placeholder="Select" name="color" onChange={(e) => setSDG(e.target.value)} options={SDGOptions} /> <div className="add-proj"> <button>Add Project</button> </div> {error && <div className="error">{error}</div>} </form> ) } export default ProjectAdminForm
该react-select组件在React类组件中可正常运行,请问为何在箭头函数组件中出现此报错?
问题原因与解决方案
核心错误原因
这和组件是箭头函数还是类组件无关,问题出在react-select的onChange回调逻辑:
- 原生
<input>的onChange接收事件对象,需要通过e.target.value获取值; - 但
react-select的onChange直接返回选中的选项对象(比如{value: 'SDG 1: No Poverty', label: 'SDG 1: No Poverty'}),没有target属性,所以访问e.target.value会触发Cannot read properties of undefined (reading 'value')错误。
修正步骤
- 修改
onChange逻辑:直接取选中选项的value属性,同时补充value属性确保选中状态同步:
<Select className="basic-single" classNamePrefix="select" placeholder="Select" name="color" onChange={(selectedOption) => setSDG(selectedOption.value)} options={SDGOptions} value={SDGOptions.find(option => option.value === sdg)} />
- 补充未定义的
error状态:组件中使用了setError但未初始化该状态,需添加:
const [error, setError] = useState('')
- 修复
fetch中的json调用:response.json是方法,必须加括号执行:
const json = await response.json()
完整修正后的组件代码
import { useState } from "react"; import { SDGOptions } from "../FilterComponents/CategoryArrays/SdgOptions"; import Multiselect from "multiselect-react-dropdown" import Select from 'react-select'; const ProjectAdminForm = () => { const [sdg, setSDG] = useState('') const [error, setError] = useState('') const handleSubmit = async (e) => { e.preventDefault() console.log('button clicked') const project = {sdg} console.log(project) const response = await fetch('/api/projects', { method: 'POST', body: JSON.stringify(project), headers: { 'Content-Type': 'application/json' } }) const json = await response.json() if (!response.ok) { setError(json.error) } if (response.ok) { setSDG('') setError('') alert('Project added!') console.log('new project added', json) } } return ( <form className="create project-form" onSubmit={handleSubmit}> <h2 style={{textAlign: "center"}}>Add a New Project</h2> <hr /> <label>Sustainable Development Goal:</label> <Select className="basic-single" classNamePrefix="select" placeholder="Select" name="color" onChange={(selectedOption) => setSDG(selectedOption.value)} options={SDGOptions} value={SDGOptions.find(option => option.value === sdg)} /> <div className="add-proj"> <button>Add Project</button> </div> {error && <div className="error">{error}</div>} </form> ) } export default ProjectAdminForm
内容的提问来源于stack exchange,提问作者Soccerball123
相关产品推荐
相关产品推荐

