React点击FaPlus按钮渲染表单及保存数据至props文件问题
问题解决指南
一、解决"añadirCurso未定义"的错误
你的代码里有几个核心问题导致这个报错:
añadirCurso函数没有用const/let声明,严格模式下会被判定为未定义变量;- 没有用React状态管理表单的显示/隐藏逻辑,直接写函数无法触发组件重新渲染;
- 带FaPlus图标的按钮没有绑定点击事件,无法触发表单显示。
修改后的完整代码:
import React, { useState } from "react"; import Button from 'react-bootstrap/Button'; import {aulas} from '../props/aulas'; import Container from 'react-bootstrap/Container'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import {FaPlus} from 'react-icons/fa'; import { useNavigate } from "react-router-dom"; export default function AdministrarCurso_Preceptor(){ const navigate= useNavigate(); // 用useState管理表单显示状态,初始为隐藏 const [mostrarFormulario, setMostrarFormulario] = useState(false); // 定义表单渲染函数 const renderFormulario = () => { return ( <div> <form onSubmit={handleSubmit}> <legend>Añadir Curso</legend> <label htmlFor="usuario">Nombre de Usuario</label> <br/> <input required type="text" name="usuario" defaultValue="" /> <br/> <button type="submit">Guardar</button> </form> </div> ) } // 表单提交处理函数(先占位,后面完善) const handleSubmit = (e) => { e.preventDefault(); // 后续添加数据保存逻辑 } return( <Container> <AppBar style={{background: 'transparent', boxShadow: 'none'}}> <Toolbar> {/* 绑定点击事件,切换表单显示状态 */} <Button className="btn btn-success" sx={{flexGrow: 1}} onClick={() => setMostrarFormulario(!mostrarFormulario)}> <FaPlus/> </Button> <Button onClick={()=> navigate('/LoginForm')}>Cerrar Sesión</Button> </Toolbar> </AppBar> {/* 条件渲染表单:状态为true时显示 */} {mostrarFormulario && renderFormulario()} <div className="row"> {aulas.map((aula, i) => ( <div key={i} className="col-md-4" style={{paddingBottom: '10px', paddingTop: '5px'}}> <Button className={(aula.estado==='sucio'? 'btn btn-danger': 'btn btn-success')}>{aula.año}{aula.division}</Button> </div> ))} </div> </Container> ) }
二、表单提交后自动渲染新按钮的实现
不能直接把数据保存到静态的props文件——静态JS文件在运行时是只读的,无法动态修改。推荐两种可行方案:
方案1:组件内状态管理(临时存储)
把导入的静态aulas转为组件内部状态,更新状态时React会自动重新渲染列表:
import React, { useState } from "react"; // 重命名初始数据,避免和组件状态冲突 import {aulas as aulasIniciales} from '../props/aulas'; export default function AdministrarCurso_Preceptor(){ const navigate= useNavigate(); const [mostrarFormulario, setMostrarFormulario] = useState(false); // 将初始数据转为组件状态 const [aulas, setAulas] = useState(aulasIniciales); const handleSubmit = (e) => { e.preventDefault(); // 获取表单输入值 const formData = new FormData(e.target); const usuario = formData.get('usuario'); const año = formData.get('año'); const division = formData.get('division'); // 构造新的教室数据(匹配原有数据结构) const nuevoAula = { año, division, estado: 'limpio', usuario }; // 更新状态,添加新数据 setAulas([...aulas, nuevoAula]); // 隐藏表单 setMostrarFormulario(false); } const renderFormulario = () => { return ( <div> <form onSubmit={handleSubmit}> <legend>Añadir Curso</legend> <label htmlFor="usuario">Nombre de Usuario</label> <br/> <input required type="text" name="usuario" /> <br/> <label htmlFor="año">Año</label> <br/> <input required type="text" name="año" /> <br/> <label htmlFor="division">División</label> <br/> <input required type="text" name="division" /> <br/> <button type="submit">Guardar Curso</button> </form> </div> ) } // 其余渲染代码不变 }
方案2:本地存储(刷新页面数据不丢失)
如果希望刷新页面后新增的数据依然保留,可以结合localStorage:
// 初始化状态时优先读取本地存储 const [aulas, setAulas] = useState(() => { const storedData = localStorage.getItem('aulas'); return storedData ? JSON.parse(storedData) : aulasIniciales; }); const handleSubmit = (e) => { e.preventDefault(); // ...构造nuevoAula逻辑不变 const nuevasAulas = [...aulas, nuevoAula]; setAulas(nuevasAulas); // 同步保存到本地存储 localStorage.setItem('aulas', JSON.stringify(nuevasAulas)); }
补充:OnClick和OnPress的区别
onClick是React Web端的标准点击事件,适用于鼠标交互场景;onPress是React Native的触摸事件,针对移动端触摸操作,Web项目用onClick即可。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

