You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中usePlacesAutocomplete组件二次进入失效问题排查

排查Next.js中usePlacesAutocomplete路由切换后失效的问题

核心原因分析

这种问题通常和Next.js客户端路由特性、Google Places脚本的初始化逻辑直接相关:

  • Google Places脚本未重新初始化:Next.js客户端导航(比如用Link组件跳转)不会刷新整个页面,Google Places脚本可能已加载,但usePlacesAutocomplete内部的初始化钩子在组件重新挂载时未触发,导致ready状态无法更新为true。
  • 组件状态残留:路由切换返回时,组件的内部状态(如输入框值、联想列表状态)未重置,导致联想功能的监听逻辑没有重新绑定。
  • 依赖项配置错误:如果封装了自定义组件,usePlacesAutocomplete的依赖项设置不当,会导致组件重新挂载时钩子没有重新执行初始化。

具体解决步骤

1. 绑定脚本加载与组件初始化

若使用@react-google-maps/api库,将LoadScript组件放在使用usePlacesAutocomplete的组件内部,同时确保组件在客户端环境运行(App Router需添加'use client'指令):

'use client';
import { LoadScript } from '@react-google-maps/api';
import usePlacesAutocomplete from '@react-google-maps/api/lib/places/usePlacesAutocomplete';

export default function AddressInput() {
  const { ready, value, suggestions, setValue, clearSuggestions } = usePlacesAutocomplete({
    requestOptions: {
      componentRestrictions: { country: 'cn' }, // 示例:限制国内地址
    },
  });

  return (
    <LoadScript
      googleMapsApiKey="YOUR_API_KEY"
      libraries={['places']}
    >
      <input
        value={value}
        onChange={(e) => setValue(e.target.value)}
        disabled={!ready}
        placeholder="输入地址"
      />
      {/* 渲染联想建议列表 */}
      {suggestions.length > 0 && (
        <ul>
          {suggestions.map((suggestion) => (
            <li key={suggestion.place_id} onClick={() => setValue(suggestion.description)}>
              {suggestion.description}
            </li>
          ))}
        </ul>
      )}
    </LoadScript>
  );
}

这样每次组件挂载时,LoadScript都会检查Google Places脚本的加载状态,确保usePlacesAutocomplete能正确初始化。

2. 监听路由变化重置状态

利用Next.js的路由钩子监听路径变化,当回到当前页面时手动重置autocomplete的状态:

'use client';
import { usePathname } from 'next/navigation';
import { useEffect } from 'react';
import usePlacesAutocomplete from '@react-google-maps/api/lib/places/usePlacesAutocomplete';

export default function AddressInput() {
  const pathname = usePathname();
  const { ready, value, setValue, clearSuggestions, refresh } = usePlacesAutocomplete({
    requestOptions: { /* 你的配置 */ },
  });

  useEffect(() => {
    // 假设当前页面路径是 /address
    if (pathname === '/address') {
      setValue('');
      clearSuggestions();
      // 调用refresh方法重新初始化autocomplete(部分版本的库支持)
      refresh?.();
    }
  }, [pathname, setValue, clearSuggestions, refresh]);

  // 渲染输入框和建议列表...
}

3. 清理事件监听避免状态残留

如果手动绑定了输入框的事件监听,务必在组件卸载时移除,防止状态残留:

'use client';
import { useEffect, useRef } from 'react';
import usePlacesAutocomplete from '@react-google-maps/api/lib/places/usePlacesAutocomplete';

export default function AddressInput() {
  const inputRef = useRef(null);
  const { setValue } = usePlacesAutocomplete({ /* 配置 */ });

  useEffect(() => {
    const handleInput = (e) => setValue(e.target.value);
    inputRef.current?.addEventListener('input', handleInput);

    // 卸载时移除监听
    return () => {
      inputRef.current?.removeEventListener('input', handleInput);
    };
  }, [setValue]);

  return <input ref={inputRef} />;
}

4. 避免全局加载脚本

不要在layout.js(App Router)或_app.js(Pages Router)中全局加载Google Maps脚本,而是在需要的组件内部加载,避免路由切换时的脚本冲突。

内容的提问来源于stack exchange,提问作者Nicolas Castera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:55:42