Next.js中如何在点击事件中调用自定义Hook?外部库调用失败
在React onClick事件中调用Daum Postcode自定义Hook失效的解决办法
问题描述
我需要使用Daum Postcode外部库,但调用出现问题。以下是自定义Hook代码:
const useDaumPostTest = () => { const Test = (asdsa: string) => { console.log(asdsa) const Element = ( <> <Script defer src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js" strategy="beforeInteractive" /> <Script> { ` new daum.Postcode({ oncomplete: function(data) { } }).open(); `} </Script> </> ) return Element } return {Test} } export default useDaumPostTest
当直接在组件中渲染Test返回的内容时(如{test})可以正常工作,但将Test函数放在点击事件处理函数handleClicks中调用时却无法正常运行。请问如何在onClick事件中使用该自定义Hook?
解决思路与代码调整
当前Hook的设计逻辑存在问题:Test函数返回的是包含<Script>的JSX元素,只有当这些元素被渲染到DOM中时,脚本才会加载并执行弹窗逻辑。但在点击事件里调用Test()只是得到了JSX对象,并没有将其挂载到DOM,所以不会触发任何效果。
正确的做法是将脚本加载和弹窗触发逻辑分离:提前加载脚本(或按需动态加载),在点击事件中直接调用Daum Postcode的API。
修改后的自定义Hook(通用版,不依赖框架特定组件)
import { useEffect, useState } from 'react'; const useDaumPostTest = () => { const [isScriptLoaded, setIsScriptLoaded] = useState(false); useEffect(() => { // 检查脚本是否已全局加载 if (typeof window !== 'undefined' && window.daum?.Postcode) { setIsScriptLoaded(true); return; } // 动态创建脚本标签加载Daum Postcode库 const script = document.createElement('script'); script.src = '//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js'; script.defer = true; script.onload = () => setIsScriptLoaded(true); script.onerror = () => console.error('Daum Postcode脚本加载失败'); document.body.appendChild(script); // 组件卸载时清理脚本(可选) return () => script.parentNode?.removeChild(script); }, []); const openPostcode = (param: string) => { console.log(param); if (!isScriptLoaded) { console.error('Daum Postcode脚本未加载完成,请稍后重试'); return; } // 直接调用Daum地址选择器API new window.daum.Postcode({ oncomplete: function(data) { // 这里添加地址选择完成后的处理逻辑,比如填充表单 console.log('选中的地址数据:', data); } }).open(); }; return { openPostcode }; }; export default useDaumPostTest;
组件中使用方式
import useDaumPostTest from './useDaumPostTest'; const AddressComponent = () => { const { openPostcode } = useDaumPostTest(); return ( <button onClick={() => openPostcode('test参数')}>打开地址选择弹窗</button> ); }; export default AddressComponent;
关键说明
- 脚本通过动态创建
<script>标签加载,确保在组件挂载时就开始加载,避免点击时才加载导致的延迟。 - 通过
isScriptLoaded状态判断脚本是否加载完成,防止调用API时出现daum未定义的错误。 openPostcode函数直接在点击事件中调用,无需返回JSX,逻辑更清晰,符合事件处理的常规写法。
内容的提问来源于stack exchange,提问作者childReact
相关产品推荐
相关产品推荐

