组件在提交时不会渲染。

huangapple go评论57阅读模式
英文:

Component won't render on submit

问题

以下是您要翻译的内容:

"Hope you can help me with this. So I am trying to use IP address to get latitude and longitude and therefore get a location on a map when a new IP is submitted using axios and react-query but can't find out what am I doing wrong.
I tried with only useState and then setting setIp(data); to handleSubmit but it didn't work as well.
I always get undefined data when refreshing the page so I handled that like this { geoData && <CreateMap ...

Is it even the right approach with react-query? Is this how I fetch the data?
Thank you for your help!"

"I have 2 components called Input and CreateMap.

Input.jsx:

import React, { useState } from "react";
import axios from "axios";
import CreateMap from "./CreateMap";
import { useQuery } from "@tanstack/react-query";

const InputComponent = () => {
const [ip, setIp] = useState("8.8.8.8");
const [geoData, setGeoData] = useState();

const { isLoading, isError, data, error } = useQuery({
queryKey: ["posts"],
queryFn: async () => {
try {
const response = await axios.get(
https://api.ipgeolocation.io/ipgeo?apiKey=e1ba80b5c7a64f0fb61db1f286d78562&ip=${ip}
);
return response.data;
} catch (error) {
throw new Error(error);
}
},
});

if (isLoading) {
return

Loading...

;
}
if (isError) {
return

Error: {error.message}

;
}

const handleIpChange = (e) => {
setIp(e.target.value);
};

const handleSubmit = (e) => {
e.preventDefault();
setGeoData(data)
};

return (




{ geoData && }

);
};

export default InputComponent;

CreateMap.jsx

import React from "react";
import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";
import { Icon } from "leaflet";

import "./Map.css";

const CreateMap = ({ lat, lng }) => {

return (

<MapContainer
style={{ height: "480px", width: "100%" }}
center={[lat, lng]}
zoom={12}
>
/>

);
};

export default CreateMap;

and App.js

import React from 'react'
import Input from './components/Input'

const App = () => {

return (

App

)
}

export default App"

英文:

Hope you can help me with this. So I am trying to use IP address to get latitude and longitude and therefore get a location on a map when an new IP is submitted using axios and react-query but can't find out what am I doing wrong.
I tried with only useState and then setting setIp(data); to handleSubmit but it didn't work as well.
I always get undefined data when refresh page so I handled that like this { geoData &amp;&amp; &lt;CreateMap ...

Is it even right approach with react-query? Is this how I fetch the data?
Thank you for your help!

I have 2 components called Input and CreateMap.

Input.jsx:

import React, { useState } from &quot;react&quot;;
import axios from &quot;axios&quot;;
import CreateMap from &quot;./CreateMap&quot;;
import { useQuery } from &quot;@tanstack/react-query&quot;;

const InputComponent = () =&gt; {
  const [ip, setIp] = useState(&quot;8.8.8.8&quot;);
  const [geoData, setGeoData] = useState();

  const { isLoading, isError, data, error } = useQuery({
    queryKey: [&quot;posts&quot;],
    queryFn: async () =&gt; {
      try {
        const response = await axios.get(
          `https://api.ipgeolocation.io/ipgeo?apiKey=e1ba80b5c7a64f0fb61db1f286d78562&amp;ip=${ip}`
        );
        return response.data;
      } catch (error) {
        throw new Error(error);
      }
    },
  });

  if (isLoading) {
    return &lt;h1&gt;Loading...&lt;/h1&gt;;
  }
  if (isError) {
    return &lt;h1&gt;Error: {error.message}&lt;/h1&gt;;
  }

  const handleIpChange = (e) =&gt; {
    setIp(e.target.value);
  };

  const handleSubmit = (e) =&gt; {
    e.preventDefault();
    setGeoData(data)
  };

  return (
    &lt;form onSubmit={handleSubmit}&gt;
      &lt;label&gt;Write your IP address: &lt;/label&gt;
      &lt;input type=&quot;text&quot; defaultValue={ip} onChange={handleIpChange} /&gt;
      &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
      { geoData &amp;&amp; &lt;CreateMap lat={geoData.latitude} lng={geoData.longitude} /&gt; }
    &lt;/form&gt;
  );
};

export default InputComponent;

CreateMap.jsx

import React from &quot;react&quot;;
import { MapContainer, Marker, Popup, TileLayer } from &quot;react-leaflet&quot;;
import { Icon } from &quot;leaflet&quot;;

import &quot;./Map.css&quot;;


const CreateMap = ({ lat, lng }) =&gt; {
 
  return (
    &lt;div&gt;
        &lt;MapContainer
          style={{ height: &quot;480px&quot;, width: &quot;100%&quot; }}
          center={[lat, lng]}
          zoom={12}
        &gt;
          &lt;TileLayer
            url=&quot;https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png&quot;
            attribution=&#39;&amp;copy; &lt;a href=&quot;http://osm.org/copyright&quot;&gt;OpenStreetMap&lt;/a&gt; contributors&#39;
          /&gt;
        &lt;/MapContainer&gt;
    &lt;/div&gt;

  );
};

export default CreateMap;

and App.js

import React from &#39;react&#39;
import Input from &#39;./components/Input&#39;


const App = () =&gt; {

  return (
    &lt;div&gt;
      &lt;h1&gt;App&lt;/h1&gt;
      &lt;Input /&gt;
    &lt;/div&gt;
  )
}

export default App

答案1

得分: 2

以下是您提供的代码的翻译部分:

这里应该使用 `react-query` 中的 `refetch`类似这样就可以了

    const InputComponent = () => {
      const [ip, setIp] = useState("8.8.8.8");
    
      const { isLoading, isError, data, error, refetch } = useQuery({
        queryKey: ["posts"],
        queryFn: async () => {
          try {
            const response = await axios.get(
              `https://api.ipgeolocation.io/ipgeo?apiKey=e1ba80b5c7a64f0fb61db1f286d78562&ip=${ip}`
            );
            return response.data;
          } catch (error) {
            throw new Error(error);
          }
        },
        enabled: false
      });
    
      if (isLoading) {
        return <h1>Loading...</h1>;
      }
      if (isError) {
        return <h1>Error: {error.message}</h1>;
      }
    
      const handleIpChange = (e) => {
        setIp(e.target.value);
      };
    
      const handleSubmit = async (e) => {
        e.preventDefault();
        refetch();
      };
    
      return (
        <form onSubmit={handleSubmit}>
          <label>输入您的IP地址 </label>
          <input type="text" defaultValue={ip} onChange={handleIpChange} />
          <button type="submit">提交</button>
          { data && <CreateMap lat={data.latitude} lng={data.longitude} /> }
        </form>
      );
    };

对于重新渲染创建一个控制组件

    function UpdateCenter({ center }) {
      const map = useMap();
      map.setView(center);
      return null;
    }

并将其添加到您的 CreateMap 组件中

    const CreateMap = ({ lat, lng }) => {
      return (
        <div>
            <MapContainer
              style={{ height: "480px", width: "100%" }}
              center={[lat, lng]}
              zoom={12}
              
            >
              <TileLayer
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
              />
              <UpdateCenter center={[lat, lng]} />
            </MapContainer>
        </div>
    
      );
    };

请注意,我已经将HTML标签和JavaScript代码进行了翻译。如果您需要更多帮助或有其他问题,请告诉我。

英文:

Something like this should be good with the refetch from react-query

const InputComponent = () =&gt; {
const [ip, setIp] = useState(&quot;8.8.8.8&quot;);
const { isLoading, isError, data, error, refetch } = useQuery({
queryKey: [&quot;posts&quot;],
queryFn: async () =&gt; {
try {
const response = await axios.get(
`https://api.ipgeolocation.io/ipgeo?apiKey=e1ba80b5c7a64f0fb61db1f286d78562&amp;ip=${ip}`
);
return response.data;
} catch (error) {
throw new Error(error);
}
},
enabled: false
});
if (isLoading) {
return &lt;h1&gt;Loading...&lt;/h1&gt;;
}
if (isError) {
return &lt;h1&gt;Error: {error.message}&lt;/h1&gt;;
}
const handleIpChange = (e) =&gt; {
setIp(e.target.value);
};
const handleSubmit = async (e) =&gt; {
e.preventDefault();
refetch();
};
return (
&lt;form onSubmit={handleSubmit}&gt;
&lt;label&gt;Write your IP address: &lt;/label&gt;
&lt;input type=&quot;text&quot; defaultValue={ip} onChange={handleIpChange} /&gt;
&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
{ data &amp;&amp; &lt;CreateMap lat={data.latitude} lng={data.longitude} /&gt; }
&lt;/form&gt;
);
};

For the rerender, create a control component :

function UpdateCenter({ center }) {
const map = useMap();
map.setView(center);
return null;
}

And add it in your CreateMap :

const CreateMap = ({ lat, lng }) =&gt; {
return (
&lt;div&gt;
&lt;MapContainer
style={{ height: &quot;480px&quot;, width: &quot;100%&quot; }}
center={[lat, lng]}
zoom={12}
&gt;
&lt;TileLayer
url=&quot;https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png&quot;
attribution=&#39;&amp;copy; &lt;a href=&quot;http://osm.org/copyright&quot;&gt;OpenStreetMap&lt;/a&gt; contributors&#39;
/&gt;
&lt;UpdateCenter center={[lat, lng]} /&gt;
&lt;/MapContainer&gt;
&lt;/div&gt;
);
};

huangapple
  • 本文由 发表于 2023年5月14日 00:13:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76243719.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定