Next.js模态框加载时获取数据问题求助
问题修复:工时表应用中Select字段无法填充用户数据
问题根源
- Fetch API未正确解析响应:直接将
fetch返回的Response对象存入state,而非解析后的用户数组,导致Select组件无法读取有效数据渲染选项。 - 初始状态错误:
data初始值设为null,API请求完成前调用options.map()会触发Cannot read properties of null (reading 'map')错误。
解决方案
- 正确解析API响应:在
fetch回调中调用response.json()将响应转换为JSON格式的用户数组。 - 初始化空数组作为默认值:将
data初始状态设为[],避免未加载完成时的map报错。 - 添加错误处理:捕获API请求异常,便于调试问题。
- 可选:添加加载状态:数据加载过程中给用户提示,提升体验。
修复后的projectform.js代码
import { useForm } from 'react-hook-form'; import Input from '../form-components/input'; import Button from '../form-components/button'; import Select from '../form-components/select'; import { useState, useEffect } from 'react'; const ProjectForm = () => { const { register, handleSubmit } = useForm(); // 初始化空数组,避免map报错 const [data, setData] = useState([]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { console.log('trigger'); fetch('http://localhost:3000/api/user') .then((response) => { // 检查响应是否成功 if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } // 解析响应为JSON return response.json(); }) .then((usersData) => { setData(usersData); setIsLoading(false); }) .catch((err) => { setError(err.message); setIsLoading(false); console.error('获取用户数据失败:', err); }); }, []); return ( <form className='flex flex-col justify-around' onSubmit={handleSubmit((formData) => console.log(formData))}> <Input label='Project Name' register={register} required /> <Select label='Project Manager' options={data} register={register} /> {/* 可选:显示加载或错误状态 */} {isLoading && <p className="text-center mt-2">加载中...</p>} {error && <p className="text-center mt-2 text-red-500">{error}</p>} <Button name='Create' type='submit' onClick={() => console.log('Test')} /> </form> ); }; export default ProjectForm;
额外优化:修改Select组件处理空数据
在select.js中添加空数据处理,避免无选项时的空白:
const Select = ({ label, register, options }) => { return ( <div className="flex items-center mt-5"> <label className="w-1/4 block text-sm font-medium text-gray-900 dark:text-white">{label}</label> <select {...register('projectManager')} className="bg-gray-50 w-3/4 m-auto border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"> {/* 当没有选项时显示提示 */} {options.length === 0 && <option value="">暂无用户数据</option>} {options.map(option => ( <option key={option.id} value={option.id}>{option.name}</option> ))} </select> </div> ); }; export default Select;
内容的提问来源于stack exchange,提问作者sgandolfo
相关产品推荐
相关产品推荐

