setState с реактивными крючками после публикации axios

#javascript #node.js #reactjs #express

#javascript #node.js #reactjs #выражать

Вопрос:

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

Login.js

    const handleLogin = (evt) => {
    //Prevent default form submission
    evt.preventDefault();

    const loginDetails = {
        username: username,
        password: password,
    }
    //send login request to api
    axios.post('http://localhost:5000/users/login', loginDetails)
    .then((res) => {
      setUser(loginDetails.username);
      history.push('/');
    })
    .catch((err) => {
      console.log('incorrect password/user');
      history.push('/login');
    })
}
 

Из-за асинхронного поведения состояние не устанавливается перед перенаправлением. Я также пытался поместить перенаправление в useEffect, но он постоянно перезагружает страницу, даже когда я перехожу в зависимость. Как я могу убедиться, что мое состояние задано, передано в мой компонент navbar в качестве реквизита, прежде чем history.push('/') оно вступит в силу.

Редактировать

App.js

   return (

    <Router history={history} >
      <div className={styles.app}>
          <Navbar user={user}/>
          <Switch>
            <Route exact path="/" component={Home}/>
            <Route path="/about" component={About}/>
            <Route exact path="/blog" component={Blog}/>
            <Route exact path="/blog/create" component={CreateBlog}/>
            <Route exact path="/blog/:id" component={ViewBlog}/>
            <Route path="/demo" component={Demo}/>
            <Route path='/resume' component={Resume}/>
            <Route 
            exact path="/login" 
            render={(props) => (
              <Login loginHandler={handleLogin}
                     usernameHandler={onChangeUsername}
                     passwordHandler={onChangePassword}/>)}
              />
            <Route exact path="/register" render={(props) => (
              <Register usernameHandler={onChangeUsername}
                        passwordHandler={onChangePassword}
                        handleRegister={handleRegister}/>
            )}/>
            
              
          </Switch>
          <Footer/>
      </div>
      
    </Router>
  );
}

export default App;
 

Комментарии:

1. можете ли вы опубликовать свой метод рендеринга.

2. Редактирование опубликовано с помощью рендеринга / возврата из App.js

3. redux — это ответ 🙂 например: jasonwatmore.com/post/2020/03/02 /…

4. Вы должны использовать setState в useEffect условно. Если loginDetails.username != null setState(loginDetails.username). В идеале, библиотеки управления состоянием, такие как redux, являются лучшим решением.

5. Использование useEffect , как предложил @Arun205, — это правильный путь. Однако условие, которое вы проверяете, равно loginDetails.username и если оно не равно нулю, то history.push('/') . Вам нужно будет добавить loginDetails.username в качестве зависимости к useEffect. Что касается другого комментария о том, что redux является ответом, это не ответ. Это просто упрощает аутентификацию пользователя, потому что состояние аутентификации может быть доступно любому компоненту. Наконец, вы должны прочитать об использовании частных маршрутов .