ReactJS中使用window prompt设置货币时提示重复弹出如何解决
问题原因
你将window.prompt直接写在了函数组件的顶层执行逻辑中,React的函数组件每次触发重渲染(父组件更新、props变更、内部状态变化等场景都会触发)时,都会从头到尾执行一遍组件内的所有顶层代码,因此每次重渲染都会调用一次prompt,导致重复弹出。
修复方案
你可以通过React内置的useEffect Hook控制prompt仅在组件首次挂载时执行1次,同时用useState存储用户输入的货币类型,避免重复询问:
import React, { useState, useEffect } from "react" function Product(props) { // 存储用户选择的货币,默认给USD作为兜底避免报错 const [userCurrency, setUserCurrency] = useState('USD') const MoreInfo = () => { alert(props.product.description); } // 依赖项为空数组,仅在组件首次挂载完成后执行1次 useEffect(() => { const inputCurrency = window.prompt("What currency do you use?") // 做合法性校验,用户点击取消时prompt返回null,此时用默认值 if (inputCurrency && /^[A-Z]{3}$/i.test(inputCurrency)) { setUserCurrency(inputCurrency.toUpperCase()) } }, []) const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: userCurrency, }) return ( <div> <h2>{props.product.name}</h2> <p>{formatter.format(props.product.price)}</p> <button onClick={MoreInfo}>More Info</button> </div> ) } export default Product
补充说明
- 代码中增加了正则校验,判断用户输入是否符合三位字母的ISO货币代码规范,避免非法输入导致
Intl.NumberFormat报错 - 如果你的页面有多个Product组件,建议把货币选择逻辑提到父组件层级,避免每个商品组件都弹出一次prompt,所有子组件共用父组件传递的货币属性即可
内容的提问来源于stack exchange,提问作者Alex Lofnes
相关产品推荐
相关产品推荐

