【问题标题】:Render functional component that is reliant on useState, on condition根据条件渲染依赖于 useState 的功能组件
【发布时间】:2020-06-13 17:29:19
【问题描述】:

我是反应、钩子和功能组件的新手。

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

Dashboard 我从 allChats 获取键(topics),我有一个由键填充的列表(activeTopic ) 主题中的值。 activeTopicuseState 挂钩,初始值应该是 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


    【解决方案1】:

    我会在 allChats 减速器中添加一个 isLoaded 标志。然后,您可以在仪表板中使用它来显示&lt;div&gt;loading&lt;/div&gt; 或上面加载的聊天视图。

    【讨论】:

    • 是的,谢谢你,这很优雅,我还将 allChats 列表组件以及 React.useState(topics[0]);这样只有在加载组件时才会调用 activeTopic 初始状态。
    猜你喜欢
    • 2019-12-28
    • 2016-06-06
    • 2020-04-27
    • 1970-01-01
    • 2021-06-08
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    相关资源
    最近更新 更多