【问题标题】:Conditional Rendering Inside A Function函数内部的条件渲染
【发布时间】:2020-06-20 00:14:20
【问题描述】:

我看过多个示例,但没有一个适合我的问题。我想在功能组件中使用条件渲染。例如,如果用户未登录且本地存储中不存在令牌,则在提交登录表单时,我想显示登录无效的消息。

if (!localStorage.getItem('token'))
  {
    return <Typography>Login Invalid</Typography>
    console.log('Login Not possible');
  }

现在,我尝试将它设为一个单独的函数,并在我的表单的 onSubmit() 中调用它。但是没有输出。

function ShowError(){
  if (!localStorage.getItem('token'))
  {
    return <Typography>Login Invalid</Typography>
  }
  else{
    console.log('Login Done');
  }
}
        return (
      <Mutation mutation={LoginMutation}>
        {(LoginMutation: any) => (
          <Container component="main" maxWidth="xs">
            <CssBaseline />
            <div style={{
              display: 'flex',
              flexDirection: 'column',
              alignItems: 'center'
            }}>
              <Formik
                initialValues={{ email: '', password: '' }}
                onSubmit={(values, actions) => {
                  setTimeout(() => {
                    alert(JSON.stringify(values, null, 2));
                    actions.setSubmitting(false);
                  }, 1000);
                }}
                validationSchema={schema}
              >
                {props => {
                  const {
                    values: { email, password },
                    errors,
                    touched,
                    handleChange,
                    isValid,
                    setFieldTouched
                  } = props;
                  const change = (name: string, e: any) => {
                    e.persist();                
                    handleChange(e);
                    setFieldTouched(name, true, false);
                    setState( prevState  => ({ ...prevState,   [name]: e.target.value }));  
                  };
                  return (
                    <form style={{ width: '100%' }} 
                    onSubmit={e => {e.preventDefault();
                    submitForm(LoginMutation); ShowError()}}>
                      <TextField
                        variant="outlined"
                        margin="normal"
                        id="email"
                        fullWidth
                        name="email"
                        helperText={touched.email ? errors.email : ""}
                        error={touched.email && Boolean(errors.email)}
                        label="Email"     
                        value={email}
                        onChange={change.bind(null, "email")}
                      />
                      <TextField
                        variant="outlined"
                        margin="normal"
                        fullWidth
                        id="password"
                        name="password"
                        helperText={touched.password ? errors.password : ""}
                        error={touched.password && Boolean(errors.password)}
                        label="Password"
                        type="password"
                        value={password}
                        onChange={change.bind(null, "password")}
                      />
                      <FormControlLabel
                        control={<Checkbox value="remember" color="primary" />}
                        label="Remember me"
                      />
                      <br />
                      <Button className='button-center'
                        type="submit"
                        disabled={!isValid || !email || !password}
                        onClick={handleOpen}
                        style={{
                          background: '#6c74cc',
                          borderRadius: 3,
                          border: 0,
                          color: 'white',
                          height: 48,
                          padding: '0 30px'
                        }}
                      >

                        Submit</Button>
                      <br></br>
                      <Grid container>
                        <Grid item xs>
                          <Link href="#" variant="body2">
                            Forgot password?
                    </Link>
                        </Grid>
                        <Grid item>
                          <Link href="#" variant="body2">
                            {"Don't have an account? Sign Up"}
                          </Link>
                        </Grid>
                      </Grid>
                      {/* <Snackbar open={open} autoHideDuration={6000} >
        <Alert severity="success">
          This is a success message!
        </Alert>
      </Snackbar> */}
                    </form>
                  )
                }}
              </Formik>
            </div>
            <Box mt={8}>
              <Copyright />
            </Box>
          </Container>
          )
        }
      </Mutation>
    );
}

export default LoginPage;

f 我这样做{localStorage.getItem('token') &amp;&amp; &lt;Typography&gt;Invalid Login&lt;/Typography&gt;}

它甚至会在表单提交之前呈现,但我只希望它在表单未提交时出现。 我该如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs typescript forms rendering


    【解决方案1】:
    function renderMe(){
      if (!localStorage.getItem('token'))
      {
        return <ErrorComponent />
      }else{
        return <Dashboard />
      }
    }
    return renderMe();
    

    这对我来说很好。我希望这能解决你的问题。

    【讨论】:

    • 不,它对我不起作用。如果您看到我的代码,我还先创建了一个单独的函数,然后尝试在我的表单上调用它。它没有给我任何输出。如果我在最终的 return() 中调用函数,在网格之后,它甚至不会作为函数出现。这只是文字。此外,即使它是函数,它也会在提交表单之前呈现。我只希望它在提交表单时检查条件并呈现。
    • okeyy 为什么你不只是将令牌存储在状态中,所以每次状态更改时它都会重新渲染组件,并检查你是否正在调用这样的方法 { renderMe() } 我猜你是不带 {} 调用所以它显示文本?
    【解决方案2】:

    您可以使用ternary 语句代替if/else

    function isLoggedIn(){
      return typeof localStorage.getItem('token') !== 'undefined'
    }
    
    ...
    
    const isLoggedIn = isLoggedIn()
    const [formSubmitted, setSubmit] = useState(false)
    const [loggedIn, setLoggedIn] = useState(isLoggedIn)
    
    useEffect(() => {
      if (loggedIn) {
       localStorage.set('token', [token])
      }
    }, [loggedIn])
    
    return (
      <Mutation mutation={LoginMutation}>
        {(LoginMutation: any) => (
          ...
          <Grid container>
            <Grid item xs>
              <Link href="#" variant="body2">
                Forgot password?
              </Link>
            </Grid>
            <Grid item>
              <Link href="#" variant="body2">
                {"Don't have an account? Sign Up"}
              </Link>
            </Grid>
            {!loggedIn && formSubmitted  ? <Typography>Login Invalid</Typography> : null}
          </Grid>
          ...
        )}
      </Mutation>
    );
    
    export default LoginPage;
    

    【讨论】:

    • 是的,我刚刚编辑了问题。但这不会在提交表单之前渲染 Typography 吗?
    • 为什么不存储表单是否已提交状态,然后使用该值来决定是否需要显示登录验证消息?
    • 能否请你给我一个简短的例子来说明如何在我的情况下做到这一点?
    • 如果我单独存储表单的状态,然后再次在表单的返回中检查它,它将如何工作?我认为它永远不会起作用,因为在提交表单之前总是会检查条件
    • 1.如果用户已经登录,即本地存储中有一个令牌,他为什么需要查看登录表单? 2. 如果您需要在用户登录时做出响应,您需要将该值存储在状态中以便您的组件可以重新渲染,您还需要通过将令牌存储在 localStorage 中来响应登录状态的变化。我已经更新了我的答案以包括这个。 3. 如果您更新状态,组件应该重新渲染并显示您的 Invalid Login 组件 - 但您需要将其连接到您的表单提交处理程序,即handleOpen
    【解决方案3】:

    为什么不简单地在最终返回之前插入一个条件。我通常这样做是为了显示一些错误。

    假设您的组件名为 LoginPage。那么——

    function LoginPage() {
     ...//do something
    
    
    
    ...//do something
    
      if (!localStorage.getItem('token'))
      {
        return <Typography>Login Invalid</Typography>
      }
    
      return(
     <Mutation mutation={LoginMutation}>
            {(LoginMutation: any) => (
              <Container component="main" maxWidth="xs">
                <CssBaseline />
                <div style={{
                  display: 'flex',
                  flexDirection: 'column',
                  alignItems: 'center'
                }}>
                  <Formik
                    initialValues={{ email: '', password: '' }}
                    onSubmit={(values, actions) => {
                      setTimeout(() => {
                        alert(JSON.stringify(values, null, 2));
                        actions.setSubmitting(false);
                      }, 1000);
                    }}
                    validationSchema={schema}
                  >
                    {props => {
                      const {
                        values: { email, password },
                        errors,
                        touched,
                        handleChange,
                        isValid,
                        setFieldTouched
                      } = props;
                      const change = (name: string, e: any) => {
                        e.persist();                
                        handleChange(e);
                        setFieldTouched(name, true, false);
                        setState( prevState  => ({ ...prevState,   [name]: e.target.value }));  
                      };
                      return (
                        <form style={{ width: '100%' }} 
                        onSubmit={e => {e.preventDefault();
                        submitForm(LoginMutation)}}>
                          <TextField
                            variant="outlined"
                            margin="normal"
                            id="email"
                            fullWidth
                            name="email"
                            helperText={touched.email ? errors.email : ""}
                            error={touched.email && Boolean(errors.email)}
                            label="Email"     
                            value={email}
                            onChange={change.bind(null, "email")}
                          />
                          <TextField
                            variant="outlined"
                            margin="normal"
                            fullWidth
                            id="password"
                            name="password"
                            helperText={touched.password ? errors.password : ""}
                            error={touched.password && Boolean(errors.password)}
                            label="Password"
                            type="password"
                            value={password}
                            onChange={change.bind(null, "password")}
                          />
                          <FormControlLabel
                            control={<Checkbox value="remember" color="primary" />}
                            label="Remember me"
                          />
                          <br />
                          <Button className='button-center'
                            type="submit"
                            disabled={!isValid || !email || !password}
                            onClick={handleOpen}
                            style={{
                              background: '#6c74cc',
                              borderRadius: 3,
                              border: 0,
                              color: 'white',
                              height: 48,
                              padding: '0 30px'
                            }}
                          >
    
                            Submit</Button>
                          <br></br>
                          <Grid container>
                            <Grid item xs>
                              <Link href="#" variant="body2">
                                Forgot password?
                        </Link>
                            </Grid>
                            <Grid item>
                              <Link href="#" variant="body2">
                                {"Don't have an account? Sign Up"}
                              </Link>
                            </Grid>
                            **IF ELSE STATEMENT HERE**
                          </Grid>
                          {/* <Snackbar open={open} autoHideDuration={6000} >
            <Alert severity="success">
              This is a success message!
            </Alert>
          </Snackbar> */}
                        </form>
                      )
                    }}
                  </Formik>
                </div>
                <Box mt={8}>
                  <Copyright />
                </Box>
              </Container>
              )
            }
          </Mutation>
     )
    }
    
    export default LoginPage;
    

    【讨论】:

    • 不,它对我不起作用。如果您看到我的代码,我还先创建了一个单独的函数,然后尝试在我的表单上调用它。它没有给我任何输出。如果我在最终的 return() 中调用函数,在网格之后,它甚至不会作为函数出现。这只是文字。此外,即使它是函数,它也会在提交表单之前呈现。我只希望它在提交表单时检查条件并呈现
    猜你喜欢
    • 2020-05-22
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 2014-02-21
    • 1970-01-01
    相关资源
    最近更新 更多