React获取表格选中行数据后无法在Modal弹窗中渲染显示
问题现象
实现表格行数据传入Modal弹窗展示功能时,表格渲染正常、点击行操作按钮能在控制台打印选中行数据,但Modal弹窗内无法渲染对应数据,控制台无报错。
效果截图:
涉及代码文件customsite.jsx原始代码如下:
import React, { useState } from 'react'; import Modal from './reusable/modal'; import useFetchData from './hooks/useFetchData'; const Customsite = ()=> { const { data, loading, } = useFetchData(); const [display, openModal] = useState(false); const closeModal = () =>{ openModal(false); } const openedModal = () =>{ openModal(true); } const getAllData = (data) =>{ console.log(data); return data; } return( <div> <div className='conatiner'> <table className="table"> <thead> <tr> <th>id</th> <th>titel</th> <th>body</th> <th>actions</th> <th>details</th> </tr> </thead> <tbody> {data.map(posts =>( <tr key={posts.id}> <th>{posts.id}</th> <th>{posts.title}</th> <th>{posts.body}</th> <th> <button className="btn btn-primary" onClick={()=> { getAllData(posts); openedModal();}}> button </button> </th> <th> <button className="btn btn-success">Success</button> </th> </tr> ))} </tbody> </table> <Modal isOpened={display} closeModal ={closeModal}> <h1>modal header</h1> <p>{getAllData}</p> </Modal> </div> </div> ) } export default Customsite
问题原因
- 没有单独定义状态存储当前选中的行数据,
getAllData仅在点击时临时接收参数打印、返回值没有被持久化存储,组件重渲染时数据会丢失 - Modal内渲染的是
getAllData函数本身,不是函数执行后返回的选中行数据,自然无法显示内容
修复方案
新增独立的state存储选中行数据,点击按钮时先把当前行数据存入该state,再打开弹窗,弹窗内直接读取这个state渲染即可。
修复后的完整代码:
import React, { useState } from 'react'; import Modal from './reusable/modal'; import useFetchData from './hooks/useFetchData'; const Customsite = ()=> { const { data, loading, } = useFetchData(); // 弹窗显示状态 const [display, setDisplay] = useState(false); // 存储当前选中的行数据 const [selectedRow, setSelectedRow] = useState(null); const closeModal = () =>{ setDisplay(false); // 关闭弹窗时清空选中数据 setSelectedRow(null); } // 点击操作按钮的处理逻辑:存数据+开弹窗 const handleRowClick = (rowData) => { setSelectedRow(rowData); setDisplay(true); } return( <div> <div className='conatiner'> <table className="table"> <thead> <tr> <th>id</th> <th>title</th> <th>body</th> <th>actions</th> <th>details</th> </tr> </thead> <tbody> {data.map(posts =>( <tr key={posts.id}> <td>{posts.id}</td> <td>{posts.title}</td> <td>{posts.body}</td> <td> <button className="btn btn-primary" onClick={()=> handleRowClick(posts)}> button </button> </td> <td> <button className="btn btn-success">Success</button> </td> </tr> ))} </tbody> </table> <Modal isOpened={display} closeModal={closeModal}> <h1>modal header</h1> {/* 选中数据存在时再渲染,避免空值报错 */} {selectedRow && ( <div> <p>ID: {selectedRow.id}</p> <p>标题: {selectedRow.title}</p> <p>内容: {selectedRow.body}</p> </div> )} </Modal> </div> </div> ) } export default Customsite
额外优化点
- 修正原代码不规范的state更新函数命名:原
openModal实际是控制弹窗显示状态的更新函数,命名和作用不匹配容易引发逻辑混乱 - 修正原表格表头拼写错误:
titel改为正确的title - 修正表格单元格语义:数据单元格用
<td>而非<th>,<th>仅用于表头单元格 - 增加空值判断,选中数据未加载时不会渲染弹窗内容,避免读取null属性报错
内容的提问来源于stack exchange,提问作者tyrese humphreys
相关产品推荐
相关产品推荐

