Я пытаюсь настроить функцию входа для приложения, которое я создаю, и у меня возникают проблемы с обновлением объекта «пользователь» после успешного входа в систему. Что странно с 'console.log ()' Я знаю, что функция запускается, и даже показывает правильную информацию, переданную в функцию, но затем состояние не обновляется. Я знаю, что он не обновляется, потому что я сделал кнопку, чтобы изменить свой статус «isAuthenticated» на «true», и это прекрасно работает, и тот же «console.log ()» показывает ту же самую информацию. Я уверен, что это может работать как класс, но я действительно пытаюсь сделать это приложение только крюками, чтобы получить больше практики. Я уверен, что нарушаю одно из правил хуков, но не знаю, как это исправить.
// App.js
function App() {
const [auth, setAuth] = React.useState({
isAuthenticated: false,
user: null, // Expects Cognito User Token
});
const setAuthStatus = authStatus => {
setAuth({...auth, isAuthenticated: authStatus});
console.log(authStatus, auth)
};
const setUser = user => {
setAuth({...auth, user: user});
};
const authProps = { // Wrapping for easy pass down
isAuthenticated: auth.isAuthenticated,
user: auth.user,
setAuthStatus: setAuthStatus,
setUser: setUser,
};
return (
<BrowserRouter>
<NavBar auth={authProps}/>
<button onClick={() => authProps.setAuthStatus(!auth.isAuthenticated)}>Click</button>
<Switch>
<Route exact path={"/"} component={LandingPage}/>
<Route exact path={"/main"} render={(props) => <MainWindow {...props} auth={authProps}/>}/>
<Route exact path={"/register"} render={(props) => <Register {...props} auth={authProps}/>}/>
<Route exact path={"/register/success"} component={RegisterSuccess}/>
<Route exact path={"/login"} render={(props) => <Login {...props} auth={authProps}/>}/>
<Route exact path={"/logout"} render={(props) => <Logout {...props} auth={authProps}/>}/>
<Route component={NotFound}/>
</Switch>
<Footer/>
</BrowserRouter>
);
}
export default App;
Я обернул функции и переменные состояния и передал их. Эта кнопка - кнопка тестирования, которая работает нормально.
Login.jsx
function Login(props) {
// styles stuff, and form validation thingies
const handleSubmit = async event => {
event.preventDefault();
clearErrorState();
try {
const user = await Auth.signIn(values.username, values.password);
props.auth.setAuthStatus(true); // *** Fires, but no state change ***
props.auth.setUser(user);
props.history.push("/main")
} catch (error) { // Sometimes returned as error, or error.message
let err = null;
!error.message ? err = {"message": error} : err = error; // Normalize
setValues({
...values, errors: {cognito: err}
});
}
};
Я даже сделал образец кнопки в форме Login.jsx, и она смогла изменить состояние с точно таким же 'props.auth.setAuthStatus 'функция, использующая тот же стиль лямбда, что и в файле приложения. js.
Мне не удалось найти ни примеров, ни кода, который, по-видимому, сталкивался с той же проблемой. Есть примеры setState внутри блоков try / catch, но ни в одном из них вы не передаете его от родителя.
- В качестве отступления, я решил не использовать Context или Redux для этого приложения в данный момент, но если Мне нужен один из них, чтобы сделать эту работу, пожалуйста, дайте мне знать, и я с удовольствием включу его. Я не использовал их, но только потому, что приложение не будет таким большим.