#javascript #reactjs
#javascript #reactjs
Вопрос:
Итак, у меня проблема, когда я использую фрагмент кода в App.js чтобы войти в систему пользователя, если у него есть сохраненный токен JWT (чтобы сохранить их вход в систему, если они покинут страницу, а затем вернутся). Я использую сокет.ввод-вывод для связи с сервером.
Проблема в том, что в моем компоненте я создаю сокет.io вызывает внутри componentDidMount(), но этот код выполняется перед App.js код, поэтому сокет еще не сохранен в моем бэкэнде. В том виде, в котором сейчас работает приложение, я сохраняю идентификаторы сокетов и идентификаторы пользователей пользователей, чтобы отслеживать открытые сокеты для каждого пользователя.
Если код componentDidMount() запускается перед сохранением вновь созданного соединения с сокетами (при открытии новой вкладки создается новый сокет) Я не могу использовать новый сокет в этом вызове.
Я зарегистрировал функции, чтобы увидеть порядок, и это то, что я получил, поэтому я подозреваю, что код componentDidMount() запускается первым.
userID empty null
usersOfCall null
socketAssign
[
{
userID: '5fb483cf93b92d651a281450',
socketIDs: [ 'hdLMOfFhFXHGyOpDAAAB' ],
socketPreserved: null
},
{
userID: '5fb47647c93e23622c4e1c10',
socketIDs: [ 'JAcC2XwLuoZTsgIiAAAC', '7vgKN-sqkqUNS7L_AAAD' ],
socketPreserved: null
}
]
Из socketAssign
приведенной ниже строки следует, что именно там я храню сокет для пользователя.
Выше это результат вызова, который я делаю изнутри componentDidMount()
userID empty null
Строка является результатом функции, которая получит идентификатор пользователя пользователя, связанного с сокетом, который отправил сигнал. Он становится нулевым, поскольку сокет еще не сохранен, поэтому он не может найти совпадений.
App.js фрагмент кода:
if(localStorage.jwtToken){
const token = localStorage.jwtToken;
const tokenDecoded = jwt_decode(token);
const user = tokenDecoded.response;
store.dispatch(userSocketAssign(user));
const currentTime = Date.now() / 1000;
if(tokenDecoded.exp < currentTime){
console.log('expired');
store.dispatch(userSocketDeassign());
window.location.href = './login';
}
}
function App() {
return (
<Provider store = {store}>
<AppComponent />
</Provider>
);
}
AppComponent просто отображает маршруты для приложения со свойствами компонента, которые указывают, какой компонент должен отображаться при выборе определенного маршрута.
class App extends Component
{
componentDidMount(){
}
render(){
return (
<Router>
<Navbar />
<Switch className = "container-fluid">
<Route exact path = "/" component = {Dashboard} />
<Route exact path = "/login" component = {Login} />
...
</Switch>
<CallReceived />
</Router>
);
}
}
Как я мог бы заставить процесс монтирования ждать, пока сокет не будет сохранен на серверной части?
Комментарии:
1. Просто используйте условный рендеринг для всей
<Router>
детали.{this.state.hasLoaded amp;amp; <Router>...</Router>}
Ответ №1:
Я предлагаю вам прочитать о цикле состояний. В зависимости от вашей ситуации вы можете установить таймер для запуска компонента. Внутри компонента попробуйте добавить setInterval для задержки, при которой приложение будет отображаться первым. Вот документация о цикле состояния https://reactjs.org/docs/state-and-lifecycle.html .
Комментарии:
1. Использование таймера для ожидания ответа API является плохой практикой и в любом случае не является необходимым (если только речь не идет о реализации пользовательского тайм-аута для запроса API)