React函数组件逐层传递role_id为undefined问题怎么解决?
问题根因
都是React入门阶段很常见的小错误,整理如下:
- 组件props接收方式错误
React组件接收的所有属性都会被打包成一个props对象传入,你直接写function ApplyModal(role_id)拿到的不是role_id的值,是整个props对象,实际的值存在props.role_id里。Apply组件的入参也有同样的问题。 sendData调用时没有传参
你在提交按钮的点击事件里写的是onClick={() => sendData()},没有把拿到的role_id传入函数,导致函数内部的role_id形参是undefined。- state异步更新+类型错误
你把role定义成了对象格式{role: ''},不仅在拼接请求URL的时候会被转成[object Object]导致请求路径错误,而且setRole是异步更新,你刚调用完就用role的值,拿到的永远是上一次的旧值,完全没必要多这一层state存role_id。
修正代码
1. 修改ApplyModal组件
把入参改成解构props里的role_id即可:
import React, {useState} from "react"; import { Modal, Button } from 'react-bootstrap'; import Apply from "./Apply"; // 这里用解构取出props里的role_id function ApplyModal({ role_id }) { const [show, setShow] = useState(false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); return ( <> <Button variant="primary" onClick={handleShow}> 申请 </Button> <Modal show={show} onHide={handleClose}> <Modal.Header closeButton> <Modal.Title>提交你的信息</Modal.Title> </Modal.Header> <Modal.Body> <Apply role_id = {role_id} /> </Modal.Body> <Modal.Footer> <Button variant="secondary" onClick={handleClose}> 关闭 </Button> </Modal.Footer> </Modal> </> ); } export default ApplyModal;
2. 修改Apply组件
修正props接收、删除冗余的role state、修正sendData调用逻辑:
import React, {useState, Fragment, useEffect} from "react"; // 同样解构取出role_id const Apply = ({ role_id }) => { const [state, setState] = useState({ name: "", email: "", }); const { name, email } = state; // 展示数据 const applyMinor = async () => { try { const res = await fetch("http://localhost:5000/freelancedashboard/freelanceprofile", { method: "POST", headers: { token: localStorage.token } }); const parseData = await res.json(); setState({name: parseData.user_name, email: parseData.user_email}) } catch (err) { console.error(err.message); } } // 提交数据,直接用props里的role_id,不用再存state const sendData = async () => { try { const body = { role: role_id, name, email }; await fetch(`http://localhost:5000/application/${role_id}`, { method: "POST", headers: { token: localStorage.token, "Content-Type": "application/json" // 建议加这个请求头,否则后端可能拿不到body }, body: JSON.stringify(body) } ); console.log(role_id, name); } catch (err) { console.error(err.message); } } useEffect(() => { applyMinor(); }, []); return ( <Fragment> <div> <div> <h1>姓名:{name}</h1> <h1>邮箱:{email}</h1> <button onClick={sendData}>提交</button> </div> </div> </Fragment> ) }; export default Apply;
其他优化建议
你现在只有三层组件,用props传递参数就足够简便了。如果后续组件嵌套层级超过5层,可以考虑用useContext来做全局状态共享,避免一层一层传props的问题。
另外你父组件table的thead定义了5列,tbody里实际渲染了7列,记得把表头补全,否则页面会出现列错位的问题。
内容的提问来源于stack exchange,提问作者Oran_Cowell
相关产品推荐
相关产品推荐

