【发布时间】:2020-06-13 17:29:19
【问题描述】:
我是反应、钩子和功能组件的新手。
我有一个 Dashboard 组件包装在上下文提供程序 Store 中,当 Store 加载它时会建立一个套接字连接,然后服务器会发送客户端所需的 DB (allChats) 数据,由 reducer dispatch 加载。
在 Dashboard 我从 allChats 获取键(topics),我有一个由键填充的列表(activeTopic ) 主题中的值。 activeTopic 与 useState 挂钩,初始值应该是 topics 中的第一个键条目。
问题是 Dashboard 在客户端收到 DB 数据之前呈现,我需要在收到 DB 有效负载后呈现 Dashboard 或呈现占位符直到 allChats 在上下文提供程序中更新并触发重新渲染。
我不能有条件地设置 useState 钩子,当我尝试有条件地返回渲染内容时,它会抛出未定义的错误,因为变量分配是在渲染触发后发生的。
App.js
import Dashboard from "./Dashboard";
import Store from './Store'
function App() {
return (
<div className="App">
<Store>
<Dashboard />
</Store>
</div>
);
}
export default App;
Store.js
let socket;
function reducer(state, action) {
switch(action.type) {
//Replace state with DB payload
case 'LOAD_MESSAGES':
return action.payload
default:
return state
}
}
export default function Store(props) {
//Hook reducer for DB data
const [allChats, dispatch] = React.useReducer(reducer, {});
if (!socket) {
socket = io(':3001');
//listen for DB data from server upon connection
socket.on('initialize', function(msg) {
dispatch({type: 'LOAD_MESSAGES', payload: msg})
})
}
return (
<CTX.Provider value={{allChats}}>
{props.children}
</CTX.Provider>
)
}
仪表板.js
export default function Dashboard() {
const classes = useStyles();
//Import DB data
const {allChats} = React.useContext(CTX);
//Get keys from DB data
const topics = Object.keys(allChats);
//Hook activeTopic, initialise with the first key entry
const [activeTopic, changeActiveTopic] = React.useState(topics[0]);
return (
<div>
<div>
{
//populate list with messages from activeTopic key of DB data
allChats[activeTopic].map((chat, i) => (
<div key={i}>
<Chip label={chat.from} className={classes.chip}/>
<Typography variant='h5' gutterBottom>{chat.msg}</Typography>
</div>))
}
</div>
</div>
)
}
我显然错过了反应、上下文和钩子生命周期的关键概念。我不想破解一个我希望能够以正确方式处理它的解决方案。 非常感谢您的帮助,谢谢。
【问题讨论】:
标签: javascript reactjs socket.io react-hooks