为什么 IFrame 不会在单击容器 div 时加载?

Why IFrame does not load on a single click on container div?

背景:

致力于 Cyber​​source Credit Card 与 React 应用程序的集成。需要在跳出 (onBlur) 字段时显示来自 API 响应的屏蔽卡号。

流量

  1. 创建了一个容器-div,其中加载了 IFrame,我输入了 CC 编号。在 blur 事件中,执行 API 调用验证并获取屏蔽卡号(如果验证成功)。

  2. 设置 maskedCardNumber 后,组件将重新呈现并在容器中显示 maskedCardNumber-div。此时我在“元素”选项卡中看到,IFrame gone 对我来说非常好。现在在我的容器中 div 没有 IFrame,而是一个屏蔽的卡号。

我要更改抄送号码

  1. 我点击输入相同的内容div,由于setMaskedCardNumber("");,屏蔽的卡号被删除。 (不是每个字符一个接一个,而是全部一次,因为我们没有那个卡号)。至此一切都很好。

问题

删除后,它应该显示新的 Iframe,因为我调用 loadIFrame(); 就像我为初始 Iframe 加载所做的那样,但奇怪的是它直到我单击 AGAIN 才显示。是的!!你没看错。我需要再次单击以加载 IFrame,这对我来说很奇怪。

目前已尝试

  1. useState(),
  2. useReducer(),
  3. 在容器内制作 <label>{maskedCardNumber}</label>-div.
  4. 正在将容器-div<div>更改为<input>

相关代码

  useEffect(() => {
    if (apiKey) {
      loadIFrame();
    }
  }, [apiKey])


const loadIFrame = () => {
let flex;
flex = new Flex(apiKey);
let microform = flex.microform();
let number = microform.createField('number', {
    placeholder: 'Enter card number'
});
number.on('load', () => {
    number.focus();
});
number.on('blur', () => {
  
    //transient token call
    microform.createToken({}, function(err, token) {
        if (err) {
            console.error(err);
            setCardError({
                ...error,
                token: "Please enter valid CC number"
            })
        } else {
            setCardError({
                ...error,
                token: ""
            });

            //permenant token call
            setMaskedCardNumber(JSON.parse(atob(token.split('.')[1]))["data"]["number"]);
            dispatch({
                type: orderActions.GET_CC_TOKEN,
                transientToken: JSON.parse(atob(token.split('.')[1]))['jti'],
                callbacks: {
                    success: (ccToken) => {
                        updateCardDetail({
                            type: "token",
                            token: ccToken
                        })
                    },
                    failure: (err) => {
                        console.error(err);
                        setCardError({
                            ...error,
                            token: "Please enter valid CC number"
                        })
                    }
                }
            })
        }
    })
});
number.load('#number-container');
}

    <div id="number-container" className="form-control" onClick={() => {
        setMaskedCardNumber("");
        loadIFrame();
      }}>
        {maskedCardNumber}
   </div>

我在这里看到的问题基本上是在加载 iFrame 后由于其异步性质对您的 setMaskedCardNumber() 调用 returns 的响应。

试试这个效果

  useEffect(()=>{
    if(maskedCardNumber === ""){
      loadIFrame()
    }
  }, [maskedCardNumber])

并从 onClick() 处理程序中删除 loadIFrame();

这将确保无论何时您清空 cardNumber 状态,iFrame 都会在成功清空时加载。

更新:

我们可以利用单useEffect.

  useEffect(() => {
    if (apiKey && !maskedCardNumber) {
      loadIFrame();
    }
  }, [apiKey, maskedCardNumber])

这样我们就可以确保仅在存在 apiKey 时才加载 IFrame,否则不要尝试加载,因为 IFrame 依赖于 apiKey。