Визуализация функционального компонента, который зависит от useState, при условии - PullRequest
0 голосов
/ 01 марта 2020

Я новичок в реагировании, хуках и функциональных компонентах.

У меня есть Панель инструментов , завернутый в провайдер контекста Store , когда Store загружает, устанавливает соединение с сокетом, затем сервер отправляет клиенту необходимые данные БД ( allChats ), которые загружаются редуктором dispatch .

В Dashboard я получаю ключи ( themes ) от allChats , у меня есть список, который заполняется ключом ( activeTopi c ) значение в темах . activeTopi c подключен с useState , начальное значение должно быть первым ключевым вводом в themes .

Проблема Dashboard рендерится до того, как клиент получит данные БД, мне нужно отрендерить Dashboard либо после получения полезной нагрузки БД, либо визуализировать заполнитель до тех пор, пока allChats не будет обновлено в поставщике контекста и повторный рендеринг запускается.

Я не могу условно установить хук useState, и когда я пытаюсь вернуть содержимое рендеринга условно, он генерирует неопределенные ошибки, потому что назначение переменных происходит после запуска рендеринга.

Приложение. 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>
  )
}

Я явно пропал ключевые концепции реакции, контекста и жизненного цикла крючка. Я не хочу найти решение, я хочу иметь возможность правильно с ним справиться. Я был бы очень признателен за помощь, спасибо.

1 Ответ

1 голос
/ 01 марта 2020

Я бы добавил флаг isLoaded в редуктор allChats. Затем вы можете использовать это на панели инструментов, чтобы показать <div>loading</div> или загруженный вид чата выше.

...