使用Remix框架从数据库加载数据,客户端为何接收不到数据?
问题分析与解决
问题根源
你在getData方法里用数组result_data = []存储键值对,但JavaScript中数组是索引型集合,当你用字符串(如keya)作为键赋值时,实际是给数组对象添加了自定义属性,而非数组的索引元素。Remix的json()方法会将数据序列化为JSON,而JSON序列化数组时只会识别数字索引对应的元素,这些字符串键的属性会被直接忽略,导致客户端接收到空数组。
修复方案
把result_data从数组改为普通对象{},这样字符串键值对会被正常序列化并传递到客户端。
修改后的代码
data.server.tsx(核心修改getData方法)
import pkg from 'pg'; const { Client } = pkg; class DB { client: Client; async getData () { return new Promise (async (resolve, reject) => { var query = "select * from my_table"; await this.client.query (query) .then ((result) => { if (result.rows.length == 0) reject ('no results'); // 将数组替换为普通对象 var result_data = {}; for (var i = 0; i < result.rows.length; i++) result_data [result.rows [i].k] = result.rows [i].v; resolve (result_data); }) .catch ((error) => { reject (error); }); }); } constructor () { this.client = new Client ({ host: '127.0.0.1', port: 5432, database: 'my_db', user: 'my_user', password: 'my_pw' }); } async connect () { await this.client.connect (); } } const db_client = new DB (); async function connect () { await db_client.connect (); } connect (); export { db_client };
可选优化:简化Promise写法
可以去掉多余的Promise嵌套,让代码更简洁:
async getData() { const query = "select * from my_table"; const result = await this.client.query(query); if (result.rows.length === 0) { throw new Error('no results'); } const result_data = {}; for (const row of result.rows) { result_data[row.k] = row.v; } return result_data; }
验证效果
修改后,服务器端打印的会是标准对象形式:
server data: { keya: 'Value A', keyb: 'Value B', keyc: 'Value C' }
客户端控制台也会收到相同的对象,可正常用于组件渲染。
内容的提问来源于stack exchange,提问作者Zephyrus
相关产品推荐
相关产品推荐

