Reactjs 使用React Usestate在组件之间传输数据问题

Reactjs 使用React Usestate在组件之间传输数据问题,reactjs,Reactjs,我们遇到了一个问题,关于Symfony4、Api平台、React和其他软件包的项目 我们创建了SearchBar.jsx,并希望在Maps.jsx 我们希望将tperfectAddress从SearchBar.jsx的使用状态转移到Maps.jsx上的const position=[] 我们在控制台日志上得到了很好的json响应,但我们不知道如何检索数据并传递它们 我们遵循上下文API、SWR和其他方法,但是我们被卡住了,所以如果您能帮助我们,我们将非常高兴 这是我们的代码: SearchBar

我们遇到了一个问题,关于Symfony4、Api平台、React和其他软件包的项目

我们创建了SearchBar.jsx,并希望在Maps.jsx

我们希望将t
perfectAddress
从SearchBar.jsx的使用状态转移到Maps.jsx上的
const position=[]

我们在控制台日志上得到了很好的json响应,但我们不知道如何检索数据并传递它们

我们遵循上下文API、SWR和其他方法,但是我们被卡住了,所以如果您能帮助我们,我们将非常高兴

这是我们的代码:

SearchBar.jsx:


import React, {useState} from "react";
import axios from 'axios';
import { withRouter } from 'react-router-dom';
import { toast } from "react-toastify";

const SearchBar = ({ history }) => {

    const [search, setSearch] = useState("");

    const [address, setAddress] = useState([]);

    const [perfectAddress, setPerfectAddress] = useState([]);

    const handleSearch = ({ currentTarget }) => {
        setSearch(currentTarget.value);
    }

    const handleSubmit = async event => {

        event.preventDefault();

            try {
               const data = await axios.get("https://nominatim.openstreetmap.org/search?q="+search+"&format=json&polygon=1&addressdetails=1")
                                       .then(reponse => reponse.data[0])

            setAddress(data);

            const latLong = [data['lat'], data['lon']];

            setPerfectAddress(latLong);

            history.push("/leaflet")
            } 
            catch (error) {
              toast.error("Impossible de charger les données");
            }
        }
        //history.replace("/leaflet")


    return (
    <>
        <form onSubmit={handleSubmit}>
            <div className="md-form active-cyan active-cyan-2 d-flex mb-3">
                <input 
                    className="form-control mr-3" 
                    type="text"
                    value={search}
                    onChange={handleSearch}
                    placeholder="Rechercher..." 
                    aria-label="Search" 
                />
                <button type="submit" className="btn btn-success">
                    Rechercher
                </button>          
            </div>
        </form>
    </>
  );
};

export default withRouter(SearchBar);

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Map, Marker, Popup, TileLayer } from "react-leaflet";
import { toast } from "react-toastify";

const Maps = (props) => {
  const [coordinates, setCoordinates] = useState([]);

  const fetchCoords = async () => {
    try {
      const data = await axios
        .get("http://localhost:8000/api/locations")
        .then((reponse) => reponse.data["hydra:member"]);

      setCoordinates(data);
    } catch (error) {
      toast.error("Impossible de charger les données");
    }
  };

  useEffect(() => {
    fetchCoords();
  }, []);

  const position = [49.442402, 1.09846];

  return (
    <>
      <Map center={position} id="mapid" zoom={12}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          maxZoom="18"
          id="mapbox/streets-v11"
        />
        {coordinates.map((maps) => {
          const ensemble = [maps.latitude, maps.longitude];
          const adresse = maps.address;
          return (
            <Marker position={ensemble}>
              <Popup>{adresse}</Popup>
            </Marker>
          );
        })}
      </Map>
    </>
  );
};

export default Maps;


从“React”导入React,{useState};
从“axios”导入axios;
从“react router dom”导入{withRouter};
从“react toastify”导入{toast};
常量搜索栏=({history})=>{
const[search,setSearch]=useState(“”);
const[address,setAddress]=useState([]);
const[perfectAddress,setPerfectAddress]=useState([]);
常量handleSearch=({currentTarget})=>{
setSearch(当前目标值);
}
const handleSubmit=异步事件=>{
event.preventDefault();
试一试{
const data=wait axios.get(“https://nominatim.openstreetmap.org/search?q=“+search+”&format=json&polygon=1&addressdetails=1”)
.然后(reponse=>reponse.data[0])
设置地址(数据);
const latLong=[data['lat'],data['lon'];
setPerfectAddress(latLong);
历史推送(“/传单”)
} 
捕获(错误){
toast.错误(“不可能的错误”);
}
}
//历史记录。替换(“/传单”)
返回(
回收机
);
};
使用路由器导出默认值(搜索栏);
来自SearchBar.jsx的Json响应:

Maps.jsx:


import React, {useState} from "react";
import axios from 'axios';
import { withRouter } from 'react-router-dom';
import { toast } from "react-toastify";

const SearchBar = ({ history }) => {

    const [search, setSearch] = useState("");

    const [address, setAddress] = useState([]);

    const [perfectAddress, setPerfectAddress] = useState([]);

    const handleSearch = ({ currentTarget }) => {
        setSearch(currentTarget.value);
    }

    const handleSubmit = async event => {

        event.preventDefault();

            try {
               const data = await axios.get("https://nominatim.openstreetmap.org/search?q="+search+"&format=json&polygon=1&addressdetails=1")
                                       .then(reponse => reponse.data[0])

            setAddress(data);

            const latLong = [data['lat'], data['lon']];

            setPerfectAddress(latLong);

            history.push("/leaflet")
            } 
            catch (error) {
              toast.error("Impossible de charger les données");
            }
        }
        //history.replace("/leaflet")


    return (
    <>
        <form onSubmit={handleSubmit}>
            <div className="md-form active-cyan active-cyan-2 d-flex mb-3">
                <input 
                    className="form-control mr-3" 
                    type="text"
                    value={search}
                    onChange={handleSearch}
                    placeholder="Rechercher..." 
                    aria-label="Search" 
                />
                <button type="submit" className="btn btn-success">
                    Rechercher
                </button>          
            </div>
        </form>
    </>
  );
};

export default withRouter(SearchBar);

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Map, Marker, Popup, TileLayer } from "react-leaflet";
import { toast } from "react-toastify";

const Maps = (props) => {
  const [coordinates, setCoordinates] = useState([]);

  const fetchCoords = async () => {
    try {
      const data = await axios
        .get("http://localhost:8000/api/locations")
        .then((reponse) => reponse.data["hydra:member"]);

      setCoordinates(data);
    } catch (error) {
      toast.error("Impossible de charger les données");
    }
  };

  useEffect(() => {
    fetchCoords();
  }, []);

  const position = [49.442402, 1.09846];

  return (
    <>
      <Map center={position} id="mapid" zoom={12}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          maxZoom="18"
          id="mapbox/streets-v11"
        />
        {coordinates.map((maps) => {
          const ensemble = [maps.latitude, maps.longitude];
          const adresse = maps.address;
          return (
            <Marker position={ensemble}>
              <Popup>{adresse}</Popup>
            </Marker>
          );
        })}
      </Map>
    </>
  );
};

export default Maps;

import React,{useState,useffect}来自“React”;
从“axios”导入axios;
从“反应传单”导入{Map,Marker,Popup,tillelayer};
从“react toastify”导入{toast};
常量贴图=(道具)=>{
const[coordinates,setCoordinates]=useState([]);
常量fetchCoords=async()=>{
试一试{
常数数据=等待axios
.get(“http://localhost:8000/api/locations")
然后((reponse)=>reponse.data[“hydra:member”]);
设置坐标(数据);
}捕获(错误){
toast.错误(“不可能的错误”);
}
};
useffect(()=>{
fetchCoords();
}, []);
常数位置=[49.442402,1.09846];
返回(
{坐标.map((贴图)=>{
常量集合=[maps.latitude,maps.longitude];
常量地址=maps.address;
返回(
{adresse}
);
})}
);
};
导出默认地图;

实际上,如果您想在路由器之间节省价值,您可以使用


1) 使用React团队提供的上下文

2) 自定义状态
mobx状态树
redux

3) 将
perfectAddress
保存在本地存储中(不推荐)


4) 作为
位置中的第二个参数传递。push(url,yourArgs)

您可以将第二个参数传递到history.push(),它可以是您想要传递的任何内容,然后可以从位置的道具访问:

history.push({  
    pathname: '/page',  
    state: { detail: 'some_value' }  
});
您可以这样访问它:

import { useEffect } from "react";
import { useLocation } from "react-router-dom";

const Page= props => {
    const location = useLocation();

    useEffect(() => {
       console.log(location.pathname); // result: '/page'
       console.log(location.state.detail); // result: 'some_value'
    }, [location]);

};

更多信息请参见:

您可以将数据作为道具传递给导航组件,例如

改变这个

history.push("/leaflet")

其中latlng是要发送的数据

现在在“地图”组件中,您可以从道具获取这些数据

const { latlng } = props.location;

这可能是使用上下文的完美场景,前提是这两个组件被渲染到不同的分支中

因此,如果您查看以下代码:

const MyContext = React.createContext({ position: [], setPosition: () => {} })

function MyParentComponent() {
  const [position, setPosition] = useState([])

  return (
    <MyContext.Provider value={{ position, setPosition }}>
      <SearchBar />
      <Maps />
    </MyContext.Provider>
  )
}
const MyContext=React.createContext({position:[],setPosition:()=>{})
函数MyParentComponent(){
const[position,setPosition]=useState([])
返回(
)
}
我们用一个默认值声明一个上下文(如果您使用此组件树之外的上下文,则提供该值)。在父组件内部,我们声明了一些状态,关键是我们现在通过
value={{position,setPosition}}

在地图和搜索栏组件中,您现在可以编写
const{position,setPosition}=useContext(MyContext)


然后可以替换
setPerfectAddress(latLong)带有
设置位置(latLong)然后在地图中,您可以使用有状态的position now。

这两个组件之间的关系是什么?最简单的方法是将状态列到一些常见的父组件上。它们之间的关系是SearchBar.jsx中的“history.push”(“/shaple”)“`。我们尝试了您的解决方案,实际上效果很好。但是,在您的示例中,searchbar组件与maps组件位于同一页面上。这不是我们的情况,我们不知道如何将搜索栏组件的结果放入地图组件中,地图组件位于不同的页面上。它还活着,它还活着,我们调整了你的提议,这是有效的。传统知识