Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当我键入其他组件的输入框时,React Mapbox组件闪烁_Javascript_Reactjs_React Hooks_React Component_React State - Fatal编程技术网

Javascript 当我键入其他组件的输入框时,React Mapbox组件闪烁

Javascript 当我键入其他组件的输入框时,React Mapbox组件闪烁,javascript,reactjs,react-hooks,react-component,react-state,Javascript,Reactjs,React Hooks,React Component,React State,我想在一个页面上有一个地图和一个输入表单。用户应该能够在输入字段中键入,点击submit,并让Mapbox组件移动到该位置 我有两个问题,我怀疑它们是相关的。当我在输入框中键入时,映射组件在每次onChange事件后闪烁。其次,当我提交表单时,地理位置被成功获取,道具在地图组件上更新,地图标记出现,但地图没有执行我在进入React Dev tools并手动更新道具时看到的整洁动画 我知道我是一个初学者,我肯定这有一千件事是错误的。如果有人知道答案,我会很高兴,但如果有人能给我指出正确的方向,我也

我想在一个页面上有一个地图和一个输入表单。用户应该能够在输入字段中键入,点击submit,并让Mapbox组件移动到该位置

我有两个问题,我怀疑它们是相关的。当我在输入框中键入时,映射组件在每次onChange事件后闪烁。其次,当我提交表单时,地理位置被成功获取,道具在地图组件上更新,地图标记出现,但地图没有执行我在进入React Dev tools并手动更新道具时看到的整洁动画

我知道我是一个初学者,我肯定这有一千件事是错误的。如果有人知道答案,我会很高兴,但如果有人能给我指出正确的方向,我也会很高兴。我花了一上午的时间浏览了React的“入门”和“挂钩”部分,并参加了一些React课程,在这些课程中,你构建了简单的应用程序,但显然有些基本的东西没有被理解。谢谢

以下是下一页:

import ReactMapboxGl, { Marker } from 'react-mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import { useState } from 'react';

export default function TestPage() {
  const Map = ReactMapboxGl({
    accessToken: process.env.NEXT_PUBLIC_MAPBOX,
  });

  const [searchLocation, setSearchLocation] = useState('');
  const [geolocate, setGeolocate] = useState({
    coordinates: [2.61878695312962, 47.8249046208979],
    isPin: false,
  });

  async function fetchGeolocate(location) {
    const url = `https://api.mapbox.com/geocoding/v5/mapbox.places/${location}.json?access_token=${process.env.NEXT_PUBLIC_MAPBOX}`;
    fetch(url)
      .then((response) => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        return response.text();
      })
      .then((myText) => {
        const json = JSON.parse(myText);
        const coordinates = json.features[0].center;
        setGeolocate({ coordinates, isPin: true });
      });
  }

  function handleInputChange(event) {
    setSearchLocation(event.target.value);
  }
  function handleForm(e) {
    e.preventDefault();
    fetchGeolocate(searchLocation);
  }

  return (
    <>
      <Map
        style="mapbox://styles/mapbox/streets-v11"
        containerStyle={{
          height: '50vh',
          width: '100vw',
        }}
        center={geolocate.coordinates}
        zoom={[3]}
      >
        {geolocate.isPin && (
          <Marker coordinates={geolocate.coordinates}>
            <span className="text-3xl" role="img" aria-label="push-pin">
              Your sense that the problems are related is right on. One issue is that you're re-initializing the 
Map
component on every render:

const Map = ReactMapboxGl({
    accessToken: process.env.NEXT_PUBLIC_MAPBOX,
  });
从'react mapbox gl'导入ReactMapboxGl,{Marker};
导入“mapbox gl/dist/mapbox gl.css”;
从“react”导入{useState};
导出默认函数TestPage(){
const Map=ReactMapboxGl({
accessToken:process.env.NEXT\u PUBLIC\u映射框,
});
const[searchLocation,setSearchLocation]=useState(“”);
const[geologite,setgeologite]=useState({
座标:[2.61878695312962,47.8249046208979],
伊斯宾:错,
});
异步函数FetchGeoLocation(位置){
常量url=`https://api.mapbox.com/geocoding/v5/mapbox.places/${location}.json?access_token=${process.env.NEXT_PUBLIC_MAPBOX}`;
获取(url)
。然后((响应)=>{
如果(!response.ok){
抛出新错误(`HTTP错误!状态:${response.status}`);
}
返回response.text();
})
。然后((myText)=>{
const json=json.parse(myText);
const coordinates=json.features[0].center;
setgeologite({坐标,isPin:true});
});
}
函数handleInputChange(事件){
setSearchLocation(事件、目标、值);
}
功能手柄(e){
e、 预防默认值();
fetchgeologite(searchLocation);
}
返回(
{geologite.isPin&&(

您对问题相关的感觉是正确的。一个问题是您正在初始化每个渲染上的
Map
组件:

const [map, setMap] = useState()
useEffect(() => {
  const mapInit = ReactMapboxGl({
    accessToken: process.env.NEXT_PUBLIC_MAPBOX,
  })
  setMap(mapInit)
}, [])
它还将阻止动画的发生(我认为),因为它将创建映射的新实例,这将导致React unmount/remount组件

编辑:下面OP的答案:在组件外部初始化 看起来您可以在任何渲染逻辑之外初始化组件

替代方法:使用状态 在功能组件中,我们希望将初始化逻辑放入(或者如果它发生在第一次渲染之前非常重要,
useLayoutEffect

最后的
[]
是关键。它防止我们的回调在第一次调用后被调用

老实说,您的组件可能非常复杂,足以保证使用类组件,您可以使用
componentDidMount
进行初始化,并且不必在每次渲染时重新计算所有这些助手函数。不过最终还是由您决定


最后一点注意:您已将
fetchgeologe
声明为
async
,这意味着不调用
。然后
在所有结果上,如果您愿意,可以使用
wait
。或者取消
async
&继续使用
承诺。然后
,这取决于您。这可能有助于澄清差异。

as@elhil s在上面的帮助下,问题基本上是我在每次渲染时重新初始化贴图。所做的只是将贴图组件初始化移出主函数。我还听取了@elhil的建议并修复了我的异步等待函数。下面的代码

从'react mapbox gl'导入ReactMapboxGl,{Marker};
导入“mapbox gl/dist/mapbox gl.css”;
从“react”导入{useState};
const Map=ReactMapboxGl({
accessToken:process.env.NEXT\u PUBLIC\u映射框,
});
导出默认函数TestPage(){
const[searchLocation,setSearchLocation]=useState(“”);
const[geologite,setgeologite]=useState({
座标:[2.61878695312962,47.8249046208979],
伊斯宾:错,
});
异步函数FetchGeoLocation(位置){
常量url=`https://api.mapbox.com/geocoding/v5/mapbox.places/${location}.json?access_token=${process.env.NEXT_PUBLIC_MAPBOX}`;
const response=等待获取(url);
如果(!response.ok){
抛出新错误(`HTTP错误!状态:${response.status}`);
}
const json=await response.json();
const coordinates=json.features[0].center;
setgeologite({坐标,isPin:true});
}
函数handleInputChange(事件){
setSearchLocation(事件、目标、值);
}
功能手柄(e){
e、 预防默认值();
fetchgeologite(searchLocation);
}
返回(
{geologite.isPin&&(

也可以考虑使用LooStudio库。这可以防止每次有人在快速输入中键入某些东西而发送请求。只有在短暂的停顿之后,才触发触发地理位置的请求。哇,这都是非常有帮助的。游荡在荒野中,很难看到你什么时候丢失了踪迹。我有一个问题。我所使用的指令是基于钩子的,而React编写的材料是基于类的。现在我很清楚,如果不同时学习这两种方法,我是不会逃脱的。让我尝试一下这些建议。非常感谢您的帮助!您的建议让我找到了解决方案。我无法将地图置于状态,也不确定这是否会发生这是一个好主意,因为地图本身就是一个组件,从我收集的信息来看