React Native:在地图上呈现标记列表
React Native: rendering a list of markers on a map
我需要你的帮助!我是本地人的新手,我遇到了这个问题:
我想在地图上显示标记列表,其中信息存储在数据库 (SQLite) 中。我正在使用 react-native-maps,所以在 MapView 组件中我有
return (
<View style={styles.sectionContainer} >
<TouchableOpacity onPress={()=>{console.log(arrayData)}} >
<Text>elements of arrayData</Text>
</TouchableOpacity>
<MapView
style={styles.map}
mapType='hybrid'
initialRegion={{
latitude: 41.73909537455833,
longitude: 12.701842524111271,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,}}
>
{ arrayData.map((item, index) => (
<Marker key={index} title={item.name} coordinate={item.coordinates} />
))}
</MapView>
</View>
);
其中 arrayData 是一个对象数组,每个对象都包含以下信息:名称和坐标。
我尝试以这种方式创建这个数组:我定义了一个初始数组,一个函数从数据库中读取元素并将其添加到数组中,最后 return arrayData(=array)。这是我的代码:
const array = [
{name: 'a', coordinates: {latitude: 41.73909537455833, longitude: 12.701842524111271,}}
];
const location=[
{latitude: 41.73767484979501, longitude: 12.703637927770613},
{latitude: 41.738562243639635, longitude: 12.701931037008762},
{latitude: 41.73870384524446, longitude: 12.700487338006495},
];
const funzione = ()=>{ // get data from database called Users
try {
db.transaction((tx) => {
tx.executeSql(
"SELECT Title FROM Users",
[],
(tx, results) => {
var len = results.rows.length;
if (len > 0) {
for(let i=0;i<len;i++){
var userTitle = results.rows.item(i).Title;
//add the element in the array
array.push({name: userTitle, coordinates: location[i]});
}
}
}
)
});
return(array);
} catch (error) {
console.log(error)
}
}
const arrayData = funzione();
现在的问题是,在 MapView 组件中,arrayData 只是初始数组,所以我只看到 1 个标记。好像这个功能不能正常工作,但是如果我 运行
console.log(数组数据);
输出是正确的,并且 arrayData 具有在数据库中读取的元素。
有人可以帮助我吗?非常感谢!
可能是因为你正在渲染地图,而从数据库中获取数据的请求是异步的,所以在组件的生命周期中,渲染地图时请求没有完成。尝试添加一个 useEffect 挂钩来更改您的信息。我添加了一些您需要做的更改:
1 - 将您的函数更改为异步并强制它等待信息...像这样:
db.transaction((tx) => {
**await** tx.executeSql(
"SELECT Title FROM Users",
[],
(tx, results) => { ...
2 - 使用 useState 钩子而不是 const 创建数组。类似于:
const [array, setArray] = useState([]);
3 - 使用钩子useEffect更新标记列表信息。像这样:
const getData = async () => {
const response = await funzione();
setArray(response);
}
useEffect(() => {
getData ();
}, [])
如有任何问题,请联系我。祝你有个美好的一天。
第一个答案是正确的,顺便说一句,您还必须将 sql 回调的主体更改为 return 一个新的对象列表:
(tx, results) => {
return (results?.rows || []).map((row, i) => ({name: row.item.Title, coordinates: location[i]}));
}
然后将它们附加到您的状态
setArray([...array, ...response]);
我需要你的帮助!我是本地人的新手,我遇到了这个问题: 我想在地图上显示标记列表,其中信息存储在数据库 (SQLite) 中。我正在使用 react-native-maps,所以在 MapView 组件中我有
return (
<View style={styles.sectionContainer} >
<TouchableOpacity onPress={()=>{console.log(arrayData)}} >
<Text>elements of arrayData</Text>
</TouchableOpacity>
<MapView
style={styles.map}
mapType='hybrid'
initialRegion={{
latitude: 41.73909537455833,
longitude: 12.701842524111271,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,}}
>
{ arrayData.map((item, index) => (
<Marker key={index} title={item.name} coordinate={item.coordinates} />
))}
</MapView>
</View>
);
其中 arrayData 是一个对象数组,每个对象都包含以下信息:名称和坐标。 我尝试以这种方式创建这个数组:我定义了一个初始数组,一个函数从数据库中读取元素并将其添加到数组中,最后 return arrayData(=array)。这是我的代码:
const array = [
{name: 'a', coordinates: {latitude: 41.73909537455833, longitude: 12.701842524111271,}}
];
const location=[
{latitude: 41.73767484979501, longitude: 12.703637927770613},
{latitude: 41.738562243639635, longitude: 12.701931037008762},
{latitude: 41.73870384524446, longitude: 12.700487338006495},
];
const funzione = ()=>{ // get data from database called Users
try {
db.transaction((tx) => {
tx.executeSql(
"SELECT Title FROM Users",
[],
(tx, results) => {
var len = results.rows.length;
if (len > 0) {
for(let i=0;i<len;i++){
var userTitle = results.rows.item(i).Title;
//add the element in the array
array.push({name: userTitle, coordinates: location[i]});
}
}
}
)
});
return(array);
} catch (error) {
console.log(error)
}
}
const arrayData = funzione();
现在的问题是,在 MapView 组件中,arrayData 只是初始数组,所以我只看到 1 个标记。好像这个功能不能正常工作,但是如果我 运行 console.log(数组数据); 输出是正确的,并且 arrayData 具有在数据库中读取的元素。 有人可以帮助我吗?非常感谢!
可能是因为你正在渲染地图,而从数据库中获取数据的请求是异步的,所以在组件的生命周期中,渲染地图时请求没有完成。尝试添加一个 useEffect 挂钩来更改您的信息。我添加了一些您需要做的更改:
1 - 将您的函数更改为异步并强制它等待信息...像这样:
db.transaction((tx) => {
**await** tx.executeSql(
"SELECT Title FROM Users",
[],
(tx, results) => { ...
2 - 使用 useState 钩子而不是 const 创建数组。类似于:
const [array, setArray] = useState([]);
3 - 使用钩子useEffect更新标记列表信息。像这样:
const getData = async () => {
const response = await funzione();
setArray(response);
}
useEffect(() => {
getData ();
}, [])
如有任何问题,请联系我。祝你有个美好的一天。
第一个答案是正确的,顺便说一句,您还必须将 sql 回调的主体更改为 return 一个新的对象列表:
(tx, results) => {
return (results?.rows || []).map((row, i) => ({name: row.item.Title, coordinates: location[i]}));
}
然后将它们附加到您的状态
setArray([...array, ...response]);