基于 React 输入字段的禁用按钮无法正常工作



所以我在选择两个字段后尝试启用一个按钮,但由于某种原因,我必须单击第二个字段两次才能触发它启用。谁能看出我做错了什么?

因此,为了确认,当我单击价格并单击 donateTo 字段时,它正在正确设置状态,但是直到我第三次或第四次单击其中一个字段之前,它不会启用底部的底部。

const DonateBox = ({ goToPayment }) => {
const [price, setPrice] = useState('');
const [donateTo, setDonateTo] = useState('');
const [isProgressDisabled, setDisabled] = useState(true);
const handleSetDonateTo = (e) => {
setDonateTo(e.target.value);
disabledCheck();
};
const handlePriceClick = (e) => {
setPrice(e.target.value);
disabledCheck();
};
const handleGoToPayment = () => {
goToPayment('paymentbox');
};
const disabledCheck = () => {
if (price && donateTo) {
setDisabled(false);
}
console.log(isProgressDisabled);
};
return (
<>
<div className={styles.donateBox}>
<p className={styles.heading}>
Give through the most effective platform for good.
</p>
<p className={styles.subheading}>
100% goes to the causes listed in the article here. You are one click
away!
</p>
<div className={styles.itemList}>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="cause"
onClick={handleSetDonateTo}
checked={donateTo === 'cause'}
/>
<span>Donate to Cause</span>
</label>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="charity"
onClick={handleSetDonateTo}
checked={donateTo === 'charity'}
/>
<span>Donate to Charity</span>
</label>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="goods"
onClick={handleSetDonateTo}
checked={donateTo === 'goods'}
/>
<span>Donate to Goods</span>
</label>
</div>
<div className={styles.priceList}>
<label
className={`${styles.priceLabel} ${
price === '25' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="25"
className={styles.priceInput}
onClick={handlePriceClick}
value="25"
/>
$25
</label>
<label
className={`${styles.priceLabel} ${
price === '50' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="50"
className={styles.priceInput}
onClick={handlePriceClick}
value="50"
/>
$50
</label>
<label
className={`${styles.priceLabel} ${
price === '75' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="75"
className={styles.priceInput}
onClick={handlePriceClick}
value="75"
/>
$75
</label>
</div>
</div>
<button
className={styles.largeButton}
onClick={handleGoToPayment}
disabled={isProgressDisabled}
>
Add Card Details
</button>
</>
);
};
export default DonateBox;

除了@adesurirey的建议之外,这是useEffect的完美场景。

更改依赖项数组中的变量时,将调用useEffect中的代码。

这意味着,如果更改了pricedonateTo,您可以自动调用disabledCheck。这样,您就不必记住在处理程序中调用disabledCheck

编辑在这样的场景中,关于useEffect的另一个好处是,您确定只有在状态更改才会调用disabledCheck。 由于变异状态是异步的,因此disabledCheck可能在实际更新状态之前正在运行。

useEffect想象setState中的回调函数(在基于类的组件上(。

// Class based comparison...
// You know for sure `disabledCheck` is only called *after* 
// state has been updated
setState({ 
some: 'newState' 
}, () => disabledCheck());

演示:

const { useState, useEffect, Fragment } = React;
const { render } = ReactDOM;
const DonateBox = ({ goToPayment }) => {
const [price, setPrice] = useState('');
const [donateTo, setDonateTo] = useState('');
const [isProgressDisabled, setDisabled] = useState(true);
const handleSetDonateTo = (e) => {
setDonateTo(e.target.value);
// disabledCheck();
};
const handlePriceClick = (e) => {
setPrice(e.target.value);
// disabledCheck();
};
const handleGoToPayment = () => {
goToPayment('paymentbox');
};
const disabledCheck = () => {
if (price !== '' && donateTo !== '') {
setDisabled(false);
}
console.log(isProgressDisabled);
};

useEffect(() => {
disabledCheck();
}, [price, donateTo]);
return (
<Fragment>
<div>
<p>
Give through the most effective platform for good.
</p>
<p>
100% goes to the causes listed in the article here. You are one click
away!
</p>
<div>
<label>
<input
type="radio"
value="cause"
onClick={handleSetDonateTo}
checked={donateTo === 'cause'}
/>
<span>Donate to Cause</span>
</label>
<label>
<input
type="radio"
value="charity"
onClick={handleSetDonateTo}
checked={donateTo === 'charity'}
/>
<span>Donate to Charity</span>
</label>
<label>
<input
type="radio"
value="goods"
onClick={handleSetDonateTo}
checked={donateTo === 'goods'}
/>
<span>Donate to Goods</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="25"
onClick={handlePriceClick}
value="25"
/>
$25
</label>
<label>
<input
type="radio"
name="50"
onClick={handlePriceClick}
value="50"
/>
$50
</label>
<label>
<input
type="radio"
name="75"
onClick={handlePriceClick}
value="75"
/>
$75
</label>
</div>
</div>
<button
onClick={handleGoToPayment}
disabled={isProgressDisabled}
>
Add Card Details
</button>
</Fragment>
);
};
const App = () => <DonateBox />
render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

您应该在输入上使用onChange事件,而不是onClick

<input
type="radio"
name="75"
className={styles.priceInput}
onChange={handlePriceClick}
value="75"
/>

最新更新