为什么React钩子不能是条件的?

huangapple go评论60阅读模式
英文:

Why cant react hooks be conditional?

问题

I am making a small web application I want the user to be able to log in when they fill out the form and change the page. When the form is submitted I want my code to check whether the data inputted is correct then send the user to a different page. How am I able to do this every time I do I just get errors saying that I cant put a hook there. I have even tried putting the hook in a separate function and then calling that function if the criteria are meet and that still doesn't work

So my question is why can't they be conditions like why can I put them in an if statement and how would I be able to fix my code so I can navigate and change the page based on an if statement results.

Code

AccountSlice.tsx

const tologin = () => {
    const Navigate = useNavigate();
    Navigate('/Home')
}

const AccountSlice = createSlice({
    name: "Account",
    initialState: { ActiveAccount: [], Accounts: [{ id: 1, email: "Member@mail.com", password: "password", isActive: false, roles: "Member" }, { id: 2, email: "Manager@mail.com", password: "password", isActive: false, roles: "Manager" }] },
    reducers: {
        LoginFunc: (state, action) => {
            let account = state.Accounts.find((account: any) => account.email == action.payload.email && account.password == action.payload.password)
            if (account != null) {
                console.log("logged in")
                state.ActiveAccount.pop()
                state.ActiveAccount.push(account)
                tologin()
            }
            else {

            }
        },
        LogOut: (state, Action) => {
            console.log("Logged Out")
        }
    }
})

export default AccountSlice.reducer;
export const { LoginFunc, LogOut } = AccountSlice.actions;

Login Component

const Login = ({ onSubmit }) => {

    const [Email, setEmail] = useState("")
    const [Password, setPassword] = useState("")

    const handleSubmit = e => {
        e.preventDefault()
        onSubmit(Email, Password)
    }

    return (
        <>
            <div className="Login">
                <div className='Login-form'>
                    <form onSubmit={handleSubmit}>
                        <div>
                            <label htmlFor="firstName">First Name</label>
                            <input type="text" value={Email} onChange={e => setEmail(e.target.value)} />
                        </div>
                        <div>
                            <label htmlFor="Password">Password</label>
                            <input type="password" value={Password} onChange={e => setPassword(e.target.value)} />
                        </div>
                        <br />
                        <button className='form-control' type="submit">Submit</button>
                    </form>
                </div>
            </div>
        </>
    )
}

const mapDispatchToProps = (dispatch) => {
    return {
        onSubmit: (Email, Password) => {
            dispatch(LoginFunc({ email: Email, password: Password }));
        },
    };
};

export default connect(mapDispatchToProps)(Login)
英文:

I am making a small web application I want the user to be able to log in when they fill out the form and change the page. When the form is submitted I want my code to check whether the data inputted is correct then send the user to a different page. How am I able to do this every time I do I just get errors saying that I cant put a hook there. I have even tried putting the hook in a separate function and then calling that function if the criteria are meet and that still doesn't work

So my question is why can't they be conditions like why can i put them in an if statement and how would I be able to fix my code so I can navigate and change the page based on an if statement results.

Code

AccountSlice.tsx

const tologin = () =&gt; {
    const Navigate = useNavigate();
    Navigate(&#39;/Home&#39;)
}


const AccountSlice = createSlice({
    name: &quot;Account&quot;,
    initialState: {ActiveAccount: [],  Accounts: [{id: 1, email: &quot;Member@mail.com&quot;, password: &quot;password&quot;, isActive:false, roles: &quot;Member&quot;},{id: 2, email: &quot;Manager@mail.com&quot;, password: &quot;password&quot;, isActive:false, roles: &quot;Manager&quot;}]},
    reducers: {
        LoginFunc : (state, action) =&gt; {
            let account= state.Accounts.find((account:any)=&gt; account.email == action.payload.email &amp;&amp; account.password == action.payload.password)
            if(account != null){
                console.log(&quot;logged in&quot;)
                state.ActiveAccount.pop()
                state.ActiveAccount.push(account)
                tologin()
            }
            else{
             
            }
        },
        LogOut : (state, Action) =&gt; {
            console.log(&quot;Logged Out&quot;)
        }
    }
}) 


export default AccountSlice.reducer;
export const { LoginFunc, LogOut} = AccountSlice.actions; 

Login Component

const Login = ({onSubmit}) =&gt; {

    const [Email, setEmail] = useState(&quot;&quot;)
    const [Password, setPassword] = useState(&quot;&quot;)

    const handleSubmit = e =&gt; {
        e.preventDefault()
        onSubmit(Email, Password)
    }

    return(
        &lt;&gt;    
            &lt;div className=&quot;Login&quot;&gt;
                &lt;div className=&#39;Login-form&#39;&gt;
                    &lt;form onSubmit={handleSubmit}&gt;
                    &lt;div&gt;
                        &lt;label htmlFor=&quot;firstName&quot;&gt;First Name&lt;/label&gt;
                        &lt;input type=&quot;text&quot; value={Email} onChange={e =&gt; setEmail(e.target.value)}/&gt;
                    &lt;/div&gt;
                    &lt;div&gt;
                        &lt;label htmlFor=&quot;Password&quot;&gt;Password&lt;/label&gt;
                        &lt;input type=&quot;password&quot; value={Password} onChange={e =&gt; setPassword(e.target.value)}/&gt;
                    &lt;/div&gt;
                    &lt;br /&gt;
                        &lt;button className=&#39;form-control&#39; type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
                    &lt;/form&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/&gt;   
    )
}

const mapDispatchToProps = (dispatch) =&gt; {
    return{ 
        onSubmit: (Email, Password) =&gt; {
            dispatch(LoginFunc({email:Email, password:Password }));
          },
    };
};

export default connect(mapDispatchToProps)(Login)

答案1

得分: 0

状态更改会触发重新渲染,但您不能渲染函数,除非它们是组件。因此,钩子只能在组件内部使用,因为它们封装状态。不要在外部定义您的函数,而是将其放在Login组件内部,并相应地导航。您可以将您的组件包装在另一个组件中,该组件将根据状态更改自动导航用户。

英文:

State changes triggers re-renders but you can't render functions unless they are components. So hooks can only be used inside components because they encapsulate states. Instead of defining your function outside, put it inside the Login component and navigate accordingly. You can wrap you component with another component that'll automatically navigate the user according to the state changes.

huangapple
  • 本文由 发表于 2023年6月22日 17:05:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76530245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定