Возможно, вы неправильно понимаете, как реагируют компоненты, которые перерисовываются, просто потому, что вы изменяете какое-то свойство в другом объекте, которое не имеет отношения к самому компоненту, даже если оно взяло свойство у этого объекта.
Хуки напрямую связаны с механизмом рендеринга реагирует и могут запускать циклы рендеринга, поэтому вы должны использовать что-то вроде этого:
const AuthView: React.FC = () => {
// if you don't put this in a state a new VM will be created when the component rerenders
const [VM] = useState(new AuthViewModel());
useEffect(() => {
// Maybe some handler code is needed?
}, VM.currentForm);
let form;
if (VM.currentForm === FORMS.SignUp) {
// Toggles the current form between FORMS.SignUp and FORMS.Login
form = <SignUpForm setCurrentForm={() => VM.setCurrentForm()} />
} else {
form = <LoginForm setCurrentForm={() => VM.setCurrentForm()} />
}
return (
<Container>
{/* Sign up card */}
<div className="mt-12">
{form}
</div>
</Container>
);
}
export default AuthView;
Я никогда не пытался наблюдать вложенное свойство через крючок, поэтому не 100% это работает.
РЕДАКТИРОВАТЬ: это не работает, но это имеет смысл, вызов рендеринга запускается, когда вы на самом деле вызываете функцию set хука useState, не совсем понимая, как реализовать этот шаблон с хуками и без чего-то вроде redux или mobx, но вот мой лучший подход:
class AuthViewModel() {
constructor(public readonly currentForm = 'LOGIN');
public setCurrentForm = () => {
if(this.currentForm === 'LOGIN')
return new AuthViewModel('SIGNUP')
else
return new AuthViewModel(); // will default to login
}
}
, а затем компонент
const AuthView: React.FC = () => {
// if you don't put this in a state a new VM will be created when the component rerenders
const [VM, setVM] = useState(new AuthViewModel());
let form;
if (VM.currentForm === FORMS.SignUp) {
// Toggles the current form between FORMS.SignUp and FORMS.Login
form = <SignUpForm setCurrentForm={() => setVM(VM.setCurrentForm())} />
} else {
form = <LoginForm setCurrentForm={() => setVM(VM.setCurrentForm())} />
}
return (
<Container>
{/* Sign up card */}
<div className="mt-12">
{form}
</div>
</Container>
);
}
export default AuthView;