为什么 IFrame 不会在单击容器 div 时加载?
Why IFrame does not load on a single click on container div?
背景:
致力于 Cybersource Credit Card 与 React 应用程序的集成。需要在跳出 (onBlur
) 字段时显示来自 API 响应的屏蔽卡号。
流量
创建了一个容器-div,其中加载了 IFrame,我输入了 CC 编号。在 blur
事件中,执行 API 调用验证并获取屏蔽卡号(如果验证成功)。
设置 maskedCardNumber
后,组件将重新呈现并在容器中显示 maskedCardNumber-div。此时我在“元素”选项卡中看到,IFrame gone 对我来说非常好。现在在我的容器中 div 没有 IFrame,而是一个屏蔽的卡号。
我要更改抄送号码
- 我点击输入相同的内容div,由于
setMaskedCardNumber("");
,屏蔽的卡号被删除。 (不是每个字符一个接一个,而是全部一次,因为我们没有那个卡号)。至此一切都很好。
问题
删除后,它应该显示新的 Iframe,因为我调用 loadIFrame();
就像我为初始 Iframe 加载所做的那样,但奇怪的是它直到我单击 AGAIN 才显示。是的!!你没看错。我需要再次单击以加载 IFrame,这对我来说很奇怪。
目前已尝试
useState()
,
useReducer()
,
- 在容器内制作
<label>{maskedCardNumber}</label>
-div.
- 正在将容器-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。
背景:
致力于 Cybersource Credit Card 与 React 应用程序的集成。需要在跳出 (onBlur
) 字段时显示来自 API 响应的屏蔽卡号。
流量
创建了一个容器-div,其中加载了 IFrame,我输入了 CC 编号。在
blur
事件中,执行 API 调用验证并获取屏蔽卡号(如果验证成功)。设置
maskedCardNumber
后,组件将重新呈现并在容器中显示 maskedCardNumber-div。此时我在“元素”选项卡中看到,IFrame gone 对我来说非常好。现在在我的容器中 div 没有 IFrame,而是一个屏蔽的卡号。
我要更改抄送号码
- 我点击输入相同的内容div,由于
setMaskedCardNumber("");
,屏蔽的卡号被删除。 (不是每个字符一个接一个,而是全部一次,因为我们没有那个卡号)。至此一切都很好。
问题
删除后,它应该显示新的 Iframe,因为我调用 loadIFrame();
就像我为初始 Iframe 加载所做的那样,但奇怪的是它直到我单击 AGAIN 才显示。是的!!你没看错。我需要再次单击以加载 IFrame,这对我来说很奇怪。
目前已尝试
useState()
,useReducer()
,- 在容器内制作
<label>{maskedCardNumber}</label>
-div. - 正在将容器-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。