javascript - 根据条件渲染依赖于 useState 的功能组件

标签 javascript reactjs socket.io react-hooks

我对 React、Hooks 和功能组件还不熟悉。

我有一个包含在上下文提供程序Store中的Dashboard组件,当Store加载时它会建立一个套接字连接,然后服务器发送客户端所需的 DB (allChats) 数据,由 reducer dispatch 加载。

仪表板中,我从allChats获取键(主题),我有一个由键(activeTopic )主题中的值(value)。 activeTopicuseState Hook ,初始值应该是 topics 中的第一个关键条目。

问题是仪表板在客户端收到数据库数据之前渲染,我需要在收到数据库有效负载后渲染仪表板或渲染占位符直到allChats 在上下文提供程序中更新并触发重新渲染。

我无法有条件地设置 useState Hook ,当我尝试有条件地返回渲染内容时,它会抛出未定义的错误,因为变量分配是在触发渲染后发生的。

App.js

import Dashboard from "./Dashboard";
import Store from './Store'

function App() {

  return (
    <div className="App">
      <Store>
        <Dashboard />
      </Store>
    </div>
  );
}

export default App;

商店.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>
  )
}

我显然错过了 react 、上下文和钩子(Hook)生命周期的关键概念。我不想找出解决方案,我希望能够以正确的方式处理它。 我非常感谢您的帮助,谢谢。

最佳答案

我会向 allChats reducer 添加一个 isLoaded 标志。然后,您可以在仪表板中使用它来显示 <div>loading</div>或上面加载的聊天 View 。

关于javascript - 根据条件渲染依赖于 useState 的功能组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60471559/

相关文章:

javascript - 如何让弹出窗口永远在最上面

javascript - 类型 '(event: React.MouseEvent) => void' 不可分配给类型 '(e?: MouseEvent<Element, MouseEvent> | undefined) => void'

javascript - 将坐标值转换为fixed64 protobuf对象

javascript - 当窗口顶部到达特定元素时向 DIV 添加一个类,否则将其删除

android - 带有 Node.js/Socket.IO 服务器和客户端的 Phonegap 应用程序中的 Android 的 WebSockets

javascript - socket.io 在每个新客户端连接时都会复制信息

reactjs - 当我单击“提交”按钮时,如何获取包含电子邮件和密码的对象

javascript - 模拟点击material-ui切换组件测试

javascript - Redux 连接的 React 应用程序 - 在我的副作用完成之前如何不渲染它?

javascript - Node js redis socket.io pubsub实时更新