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

标签 javascript reactjs

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

因此,为了确认,当我单击价格并单击 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>

关于javascript - 基于 React 输入字段的禁用按钮无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61764207/

相关文章:

javascript - 如何在首次渲染之前获取 redux 中的数据并将其设置为默认状态

javascript - 为什么我们在react native router flux中需要一个 "root"的场景

javascript - 如何处理父组件中子组件的 onClick

javascript - 无法对动态加载的元素应用 jquery 函数

javascript - 处理嵌套 React 组件的状态变化

javascript - AngularJS:将算术运算符传递给 ng-value

javascript - jquery DatePicker 按钮图像不起作用

node.js - API token 在 Flux (Redux) 存储中安全吗?

javascript - 如何在不设置全局变量的情况下确定函数是否被调用

javascript - 遍历每个工具提示以添加不同的时间戳