reactjs - 如何在 React Native 中从孙子到祖父母,然后再回到祖父母的孩子
问题描述
我是 React 的新手,所以我希望我能正确解决这个问题。首先,我有一个名为SearchLocationsScreen的屏幕。在该屏幕内,我有一个名为Map的组件,在Map内部,我有一个名为LocationMarker的自定义标记组件。在与Map组件相同的层级上,我有一个名为 CheckinModal 的自定义ModalBox。这是一个粗略的图表来帮助:
在SearchLocationsScreen中,我从 API 调用中获取位置信息。然后我将这些位置传递给我的地图组件。在我的Map组件中,我将标记的信息传递给自定义LocationMarker类并填充地图。
目标是按下标记并让CheckinModal从底部弹出并使用来自按下的特定标记的信息填充它。为此,我使用useRef钩子和forwardRef钩子将对模态的引用向下传递给LocationMarker类。我在这里打电话ref.current.open()
,模态按预期打开。
问题是我无法找到一种方法来从标记传递位置信息,将层次结构备份到屏幕并向下到模态以使用相关信息填充模态。有谁知道如何实现这一目标?我将下面的代码发布到我的屏幕、地图组件和标记组件(不包括样式)。在此先感谢您的帮助。
SearchLocationsScreen.js
const SearchLocationsScreen = ({isFocused, navigation}) => {
const {updateLocation} = useContext(CurrentLocationContext);
// hooks
const callback = useCallback((location) => {
updateLocation(location)
}, []);
const [err] = useCurrentLocation(isFocused, callback);
const [businessLocations] = useGetLocations();
const modalRef = useRef(null);
let locations = [];
if (businessLocations) {
for (let x = 0; x < businessLocations.length; x++) {
locations.push({
...businessLocations[x],
latitude: businessLocations[x].lat,
longitude: businessLocations[x].lng,
key: x,
})
}
}
return (
<View style={{flex: 1}}>
<Map markers={locations} ref={modalRef}/>
<SearchBar style={styles.searchBarStyle}/>
{err ? <View style={styles.errorContainer}><Text
style={styles.errorMessage}>{err.message}</Text></View> : null}
<CheckinModal
ref={modalRef}
/>
</View>
);
};
地图.js
const Map = ({markers}, ref) => {
const {state: {currentLocation}} = useContext(Context);
// todo figure out these error situations
if (!currentLocation) {
return (
<View style={{flex: 1}}>
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 27.848680,
longitude: -82.646560,
latitudeDelta: regions.latDelta,
longitudeDelta: regions.longDelta
}}
/>
<ActivityIndicator size='large' style={styles.indicator} />
</View>
)
}
return (
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
...currentLocation.coords,
latitudeDelta: regions.latDelta,
longitudeDelta: regions.longDelta
}}
showsUserLocation
>
{ markers ? markers.map((marker, index) => {
return <LocationMarker
ref={ref} // passing the ref down to the markers
key={index}
coordinate={marker}
title={marker.company}
waitTime={ marker.wait ? `${marker.wait} minutes` : 'Open'}
/>;
}) : null}
</MapView>
)
};
const forwardMap = React.forwardRef(Map);
export default forwardMap;
LocationMarker.js
const LocationMarker = ({company, coordinate, title, waitTime, onShowModal}, ref) => {
return (
<View>
<Marker
coordinate={coordinate}
title={title}
onPress={() => {
console.log(ref);
ref.current.open();
}}
>
<Image
source={require('../../assets/marker2.png')}
style={styles.locationMarker}/>
<View style={styles.waitContainer}><Text style={styles.waitText}>{waitTime}</Text></View>
</Marker>
</View>
)
};
const forwardMarker = React.forwardRef(LocationMarker);
export default forwardMarker;
解决方案
如果我理解正确,我建议不要forwardRef
使用 prop 从父级传递 ref ,而是ref
将其作为简单的 prop 传递。当它到达嵌套组件(在您的情况下为LocationMarker)时,您可以分配它。这是一个简化版本:
const SearchLocationsScreen = props => {
const marker_ref = useRef(null);
const modal_ref = useRef(null);
return (
<View>
<Map marker_ref={marker_ref} modal_ref={modal_ref} />
<CheckinModal marker_ref={marker_ref} modal_ref={modal_ref} />
</View>
);
};
const Map = props => {
const { marker_ref, modal_ref } = props;
return <LocationMarker marker_ref={marker_ref} modal_ref={modal_ref} />;
};
const LocationMarker = props => {
const { marker_ref, modal_ref } = props;
return <div ref={marker_ref} />;
};
const CheckinModal = props => {
const { marker_ref, modal_ref } = props;
return <div ref={modal_ref} />;
};
当 ref 到达最后一个元素时,我们使用ref=
. 请记住,这个最终元素必须是 JSX 元素,例如div
,而不是组件。
为了避免通过中间的每个组件将这些道具从祖父母传递给孩子,您可以在SearchLocationsScreen
.
推荐阅读
- java - 如何检查哪些复选框已选中,哪些未选中?
- javascript - 如何更改页面的完整 URL 但不在 jQuery 中重定向?
- jenkins - 如何从 Jenkins 管道中删除一个属性?
- php - 如何在亚马逊的单个实例中部署两个 PHP 应用程序
- vb.net - 读取资源文件失败
- javascript - 具有负索引的 2D 地图的 JS (ES6) JSON-Serializable 解决方案?
- javascript - knex 查询构建器和链中调用的方法的顺序
- php - 内连接查询中的条件
- xamarin - Xamarin iOS 上的背景图像
- r - 拟合 38 只股票的对数回报,具有多元偏斜 t 分布 R,打印参数错误