Reactjs 使用React Usestate在组件之间传输数据问题
我们遇到了一个问题,关于Symfony4、Api平台、React和其他软件包的项目 我们创建了SearchBar.jsx,并希望在Maps.jsx 我们希望将tReactjs 使用React Usestate在组件之间传输数据问题,reactjs,Reactjs,我们遇到了一个问题,关于Symfony4、Api平台、React和其他软件包的项目 我们创建了SearchBar.jsx,并希望在Maps.jsx 我们希望将tperfectAddress从SearchBar.jsx的使用状态转移到Maps.jsx上的const position=[] 我们在控制台日志上得到了很好的json响应,但我们不知道如何检索数据并传递它们 我们遵循上下文API、SWR和其他方法,但是我们被卡住了,所以如果您能帮助我们,我们将非常高兴 这是我们的代码: SearchBar
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='© <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='© <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组件位于同一页面上。这不是我们的情况,我们不知道如何将搜索栏组件的结果放入地图组件中,地图组件位于不同的页面上。它还活着,它还活着,我们调整了你的提议,这是有效的。传统知识