【问题标题】:Updating UI when entry value changes条目值更改时更新 UI
【发布时间】:2019-12-10 12:51:26
【问题描述】:

我有一个关于实时更新 UI(输入时)的问题。这是正确的方法吗?

我有这个代码:

正则表达式方法:

determineCardBrand(number) {
    var re = new RegExp("^4");
    var reMC = new RegExp(
      "/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/",
    );

    if (number.match(re) != null) {
      return "Visa";
    } else if (number.match(reMC) != null) {
      return "MasterCard";
    } else {
      return "";
    }
  }

查看代码sn-p:

 <View style={{ flexDirection: "row" }}>
                <CardLogo
                  style={styles.cardLogo}
                  cardType={
                    cardNumber === ""
                      ? "Inactive"
                      : this.determineCardBrand(cardNumber)
                  }
                />
                <TextInputMask
                  underlineColorAndroid={"transparent"}
                  type={"credit-card"}
                  maxLength={19}
                  style={[Styles.paymentCardInput, { flexGrow: 1 }]}
                  onChangeText={cardNumber => {
                    this.setState({ cardNumber });
                    this.determineCardBrand(cardNumber);
                  }}
                  value={cardNumber}
                  returnKeyType="done"
                />
              </View>

我想确定我输入的卡号是否与 CC 品牌(例如 Visa、万事达卡等)相关联。因此,当我输入卡号时,我希望卡标志根据我输入的数字而改变。 CardLogo 组件有一个 switch 语句,用于确定是否传递类型名称,例如签证,然后显示签证标志。

这是正确的方法吗?

通常,您可以从前四位数字中找到(我认为),但有时只是第一个数字,例如像签证卡..总是以四个开头。我测试了上述内容,但由于某种原因,它仅适用于 Visa 或未知 CC,不适用于万事达卡。我不确定是因为正则表达式还是我在上面设置代码的方式。

【问题讨论】:

  • 据我所知,万事达卡的第一个数字总是 5。可能这是您的正则表达式的问题。在我看来,你的方法看起来不错。
  • This 可以帮助您解决正则表达式

标签: javascript reactjs react-native


【解决方案1】:

您可以通过将 cardType 属性添加到 state 来进行一项改进,这样做您只需要确定一次卡片类型,并且它的可读性会更高,如下所示。

<View style={{ flexDirection: "row" }}>
const { cardType, cardNumber } = this.state;
<CardLogo
    style={styles.cardLogo}
    cardType={cardType}
/>
<TextInputMask
    underlineColorAndroid={"transparent"}
    type={"credit-card"}
    maxLength={19}
    style={[Styles.paymentCardInput, { flexGrow: 1 }]}
    onChangeText={cardNumber => {
        const cardType = this.determineCardBrand(cardNumber);
        this.setState({ cardNumber, cardType });
    }}
    value={cardNumber}
    returnKeyType="done"
/>

关于确定万事达卡,您的万事达卡 reg ex 似乎有问题,下面应该可以工作,正则表达式取自 regexinfo

determineCardBrand(number) {
const visa = /^4[0-9]{12}(?:[0-9]{3})?$/;
const master = /^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/;

if (visa.test(number)) {
    return "Visa";
} else if (master.test(number)) {
    return "MasterCard";
} else {
    return "";
}}

【讨论】:

  • 在您的示例中,您仍在确定每个 onChangeText 事件的卡片类型。
  • @Tim 上面的代码有什么不好?你能解释一下吗?
  • @Tim 我正在确定 cardNumberChange 上的 cardType 但 cardType 不是状态的一部分,并且确定的 cardType 在两个地方使用,一个在 this.setState 之后,另一个在 CardLogo 组件内,因此建议将cardType提升为状态,计算一次,然后从状态中使用,您是否认为在更改某些文本时使用计算某些东西证明使用useEffect是合理的?如果你想使用钩子,那么 useReducer 证明用例是合理的。
【解决方案2】:

在功能组件中,您可以使用钩子来计算 useEffect 中的卡品牌,每次卡号更改时触发。我认为这会更有效,因为 setState is asynchronous (所以你不应该假设你的状态是在 setState 之后立即调用 determineCardBrand() 时是最新的)。

[...]
const [cardNumber, setCardNumber] = useState('');
[...]
useEffect(() => {
  determineCardBrand();
}, [cardNumber]);
[...]
<TextInputMask
    underlineColorAndroid={"transparent"}
    type={"credit-card"}
    maxLength={19}
    style={[Styles.paymentCardInput, { flexGrow: 1 }]}
    onChangeText={cardNumber => {
        // const cardType = this.determineCardBrand(cardNumber); not needed anymore
        this.setCardNumber(cardNumber);
    }}
    value={cardNumber}
    returnKeyType="done"
/>

计算卡片品牌通常是一种副作用(取决于状态值),因此 useEffect 将是完美的工具(恕我直言:)。但你也可以将卡牌保存在状态中,并设置const [cardBrand, setCardBrand] = useState('')

请注意,这是函数式方法,使用 16.8 中引入的钩子,因此这对您来说可能不是一个可行的解决方案。但在基于类的组件中,状态仍然是异步的。

【讨论】:

  • 我可以在我的类组件中使用上面的钩子吗?我已经有一个类组件了?
  • 考虑到您的代码中有this.determineCardBrand(...),我假设您有一个基于类的组件。您可以轻松地将其转换为功能组件并使用挂钩:overreacted.io/…medium.com/@Zwenza/…reactjs.org/docs/hooks-faq.html。 Hooks 是一个全新的 React 特性,推送功能组件,但任何一种解决方案都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-05-22
  • 2014-01-01
相关资源
最近更新 更多