Reactjs 提交按钮禁用问题
Reactjs submit button disable issue
伙计们,我遇到了 提交按钮禁用 功能
的问题
我设置了3个条件:
- 密码应大于8个字符
- 至少应包含 1 个数字
- 客户应点击条款和隐私
只有满足这 3 个条件,布尔值“allvalid”才会被设置为 true
问题:
我发现在满足所有条件后,按钮仍然处于禁用状态
但是当我在密码提交按钮中再输入 1 个字符时,我删除了仍然有效的 1 个字符(现在是 8 个字符),但是当我再删除一个(现在是 7 个字符)时,提交按钮仍然启用,只有当我减少到 6 它再次被禁用
我希望它在满足所有条件时准确启用,在不满足时立即禁用
这是代码
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// Client shall check on the terms otherwise submit button is disabled
const checkTerms=() => {
setTerms(true)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={checkTerms}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<SubmitButton type="submit" value="Submit" disabled={!allValid}>Signup</SubmitButton>
</FormContainer>)
我认为这是由于 react.Check allvalid 状态值中挂钩的异步行为,因为它取决于其他 states.Make 确保 allvalid 状态在更新状态后正确更新它是依赖的。
我检查了你的存储库,我想我发现了问题。
首先,您的 SubmitButton 组件禁用 属性 无法正常工作。
这就是我将其更改为基本 HTML 按钮以确保正常处理值的原因。
新的喜欢的按钮应该是这样的:
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
关于复选框的另一点。您需要处理是否已选中,因此新的复选框按钮应如下所示:
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
最后一步您需要在表单中跟踪验证值,您应该再次更新状态以禁用和启用按钮。为此,您需要像这样使用 useEffect 钩子:
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
新的 checkTerms 函数将是:
const checkTerms=(e) => {
setTerms(e.target.checked)
}
我会把最后的 signupForm.jsx 给你:
import React, { useState,useEffect } from 'react';
import { useContext } from "react";
import {
BoldLink,
BoxContainer,
FormContainer,
Input,
MutedLink
} from "./common";
import { Marginer } from "../marginer";
import { AccountContext } from "./accountContext";
import styled from "styled-components";
import check from "./images/check.png";
import uncheck from "./images/uncheck.png";
const Terms = styled.h5`
width: 250px;
color: #000000;
font-weight: 500;
font-size: 10px;
z-index: 10;
margin: 0;
margin-top: 7px;
`;
const Condition= styled.div`
background: #fff;
padding: 3px;
width: 250px;
height: 30px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
const Checkbox= styled.div`
background: #fff;
padding: 3px;
width: 30px;
height: 10px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// labels and state boolean corresponding to each validation
const checkTerms=(e) => {
setTerms(e.target.checked)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
</FormContainer>
<Marginer direction="vertical" margin="1em" />
<MutedLink href="#">
Already have an account?
<BoldLink href="#" onClick={switchToSignin}>
Signin
</BoldLink>
</MutedLink>
</BoxContainer>
);
}
伙计们,我遇到了 提交按钮禁用 功能
的问题我设置了3个条件:
- 密码应大于8个字符
- 至少应包含 1 个数字
- 客户应点击条款和隐私
只有满足这 3 个条件,布尔值“allvalid”才会被设置为 true
问题: 我发现在满足所有条件后,按钮仍然处于禁用状态 但是当我在密码提交按钮中再输入 1 个字符时,我删除了仍然有效的 1 个字符(现在是 8 个字符),但是当我再删除一个(现在是 7 个字符)时,提交按钮仍然启用,只有当我减少到 6 它再次被禁用
我希望它在满足所有条件时准确启用,在不满足时立即禁用
这是代码
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// Client shall check on the terms otherwise submit button is disabled
const checkTerms=() => {
setTerms(true)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={checkTerms}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<SubmitButton type="submit" value="Submit" disabled={!allValid}>Signup</SubmitButton>
</FormContainer>)
我认为这是由于 react.Check allvalid 状态值中挂钩的异步行为,因为它取决于其他 states.Make 确保 allvalid 状态在更新状态后正确更新它是依赖的。
我检查了你的存储库,我想我发现了问题。
首先,您的 SubmitButton 组件禁用 属性 无法正常工作。
这就是我将其更改为基本 HTML 按钮以确保正常处理值的原因。
新的喜欢的按钮应该是这样的:
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
关于复选框的另一点。您需要处理是否已选中,因此新的复选框按钮应如下所示:
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
最后一步您需要在表单中跟踪验证值,您应该再次更新状态以禁用和启用按钮。为此,您需要像这样使用 useEffect 钩子:
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
新的 checkTerms 函数将是:
const checkTerms=(e) => {
setTerms(e.target.checked)
}
我会把最后的 signupForm.jsx 给你:
import React, { useState,useEffect } from 'react';
import { useContext } from "react";
import {
BoldLink,
BoxContainer,
FormContainer,
Input,
MutedLink
} from "./common";
import { Marginer } from "../marginer";
import { AccountContext } from "./accountContext";
import styled from "styled-components";
import check from "./images/check.png";
import uncheck from "./images/uncheck.png";
const Terms = styled.h5`
width: 250px;
color: #000000;
font-weight: 500;
font-size: 10px;
z-index: 10;
margin: 0;
margin-top: 7px;
`;
const Condition= styled.div`
background: #fff;
padding: 3px;
width: 250px;
height: 30px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
const Checkbox= styled.div`
background: #fff;
padding: 3px;
width: 30px;
height: 10px;
float: left;
flex:50%;
font-weight: 500;
font-size: 9px;
color: #000;
margin: 2px;
`;
export function SignupForm(props) {
const { switchToSignin } = useContext(AccountContext);
const [passwordOne, setPasswordOne] = useState("")
// booleans for password validations
const [containsN, setContainsN] = useState(false) // number
const [contains8C, setContains8C] = useState(false) // min 8 characters
// checks all validations are true
const [allValid, setAllValid] = useState(false)
const [terms,setTerms]=useState(false)
// labels and state boolean corresponding to each validation
const checkTerms=(e) => {
setTerms(e.target.checked)
}
const validatePassword = () => {
// has number
if (/\d/.test(passwordOne)) setContainsN(true)
else setContainsN(false)
// has 8 characters
if (passwordOne.length >= 8) setContains8C(true)
else setContains8C(false)
// all validations passed
if (containsN && contains8C && terms) setAllValid(true)
else setAllValid(false)
}
const handleSubmit=(e)=> {
alert('Submitted' );
e.preventDefault();
}
useEffect(()=>{
// Track all local states and validate the term
validatePassword()
},[passwordOne,terms,containsN,contains8C,validatePassword]);
return (
<BoxContainer>
<FormContainer onSubmit={handleSubmit}>
<Input type="text" placeholder="Full Name" />
<Input type="email" placeholder="Email" />
<Input type="password" placeholder="Password"
value={passwordOne}
onChange={e=>setPasswordOne(e.target.value)}
onKeyUp={validatePassword}
/>
<column>
<Condition>
<img className="check" src={contains8C?check:uncheck} alt="icon1" />
8 Characters min.
<img className="check" src={containsN?check:uncheck} alt="icon2" />
One number
</Condition>
</column>
<column>
<Checkbox>
<input type="checkbox" onClick={(e)=>checkTerms(e)}></input>
</Checkbox>
<Terms align='left'>By creating account, you agree to accept our Privacy policy, Terms of Service and Notification settings.</Terms>
</column>
<Marginer direction="vertical" margin={10} />
<button type="submit" value="Submit" disabled={!allValid}>Signup</button>
</FormContainer>
<Marginer direction="vertical" margin="1em" />
<MutedLink href="#">
Already have an account?
<BoldLink href="#" onClick={switchToSignin}>
Signin
</BoldLink>
</MutedLink>
</BoxContainer>
);
}