繁体   English   中英

如何一次有条件地更新多个元素

[英]How to update multiple elements conditionally at once

我是 React 的新手,并试图找出最好的方法是一次更新多个元素,而不必一直重复代码。

我有一个登录页面,它有几个状态:“LOGIN”、“SIGNUP”或“FORGOT_PASSWORD”。 根据当前模式,我已经能够使用 renderForm() 更改使用的表单。 但是,我还需要更新根组件中的其他一些文本,但不知道最有效的方法是什么。 当然,我可以为我必须更改的每个文本片段重复 renderForm() ,但这似乎不是很干燥。

这是我的(非常简化的)代码:

function Login() {
    const [mode, setMode] = useState("LOGIN");

    function renderForm(): ReactElement {
    return (
      <>
        {
          {
            LOGIN: <EmailPasswordForm setMode={setMode} type="login"/>,
            SIGNUP: <EmailPasswordForm setMode={setMode} type="signup"/>,
            FORGOT_PASSWORD: <ForgotPassword setMode={setMode} auth={auth} />,
          }[mode]
        }
      </>
    );
  }


    return (
    <div>
        <h2>
            Sign in to your account //title that needs to change depending on the mode
        </h2>

        {renderForm()}

        <a href="/privacy">Privacy Info</a>
        <p>
            Some text that also needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
        </p>
        <OAuthSignUpComponents/>
        <p>
            Some  more text that needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
        </p>
    </div>
    )
}

function EmailPasswordForm({setMode, type}) {

    const handleSubmit = () => {
        type == "login" ? loginLogic() : signupLogic();
    }

    return(
        <form>
            <input type="email/>
            <input type="password"/>
            <button type="button" onClick={handleSubmit}>
            { type == "login" ? <button onClick={setMode("SIGNUP")>Sign up instead</button> : <button onClick={setMode("LOGIN")>Sign in instead</button> }
        </form>
    )
}

function ForgotPasswordForm({setMode}) {
    return(
        <form>
            <input type="email/>
            <button type="button">
        </form>
    )
}

我尝试过的一件事是在 renderForm() 中使用一个开关,如下所示:

const [title, setTitle] = useState("Sign in to your account");

function renderForm(){
    switch(mode) {
        case "LOGIN":
            setTitle("Sign in to your account")
            return <EmailPasswordForm setMode={setMode} type="login"/>;
        case "SIGNUP":
            setTitle("Sign in to your account")
            return <EmailPasswordForm setMode={setMode} type="signup"/>;
        case "FORGOT_PASSWORD":
            setTitle("Reset Password")
            return <ForgotPasswordForm setMode={setMode}/>
    }
}

但这也不起作用,因为它会导致太多的重新渲染错误。

您应该在效果中使用 setTitle 以便不再出现渲染问题,因为您的主渲染 function 中不应有副作用,仅在回调和效果中。 您绝对可以将渲染表单保留为 object 而不是开关盒。 无论哪种方式都行得通。

    useEffect(() => {
    switch(mode) {
        case "LOGIN":
            setTitle("Sign in to your account")
        case "SIGNUP":
            setTitle("Sign in to your account")
        case "FORGOT_PASSWORD":
            setTitle("Reset Password")
    }
    return () => {
        // You can then set the original title of the application to clean up once they've logged in.
        // setTitle('Original Title')
    }
}, [mode])

function renderForm(){
    switch(mode) {
        case "LOGIN":
            return <EmailPasswordForm setMode={setMode} type="login"/>;
        case "SIGNUP":
            return <EmailPasswordForm setMode={setMode} type="signup"/>;
        case "FORGOT_PASSWORD":
            return <ForgotPasswordForm setMode={setMode}/>
    }
}

您甚至不必将开关盒或 object 放在内部 function 中。

  const formMap={
    LOGIN: <EmailPasswordForm setMode={setMode} type="login"/>,
    SIGNUP: <EmailPasswordForm setMode={setMode} type="signup"/>,
    FORGOT_PASSWORD: <ForgotPassword setMode={setMode} auth={auth} />,
  };

  return(<div>
    <h2>
        Sign in to your account //title that needs to change depending on the mode
    </h2>

    {formMap[mode]}

    <a href="/privacy">Privacy Info</a>
    <p>
        Some text that also needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
    </p>
    <OAuthSignUpComponents/>
    <p>
        Some  more text that needs to change depending on if the mode is "LOGIN", "SIGNUP", or "FORGOT_PASSWORD"
    </p>
</div>)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM