如何在React Native中从孙子传达到其祖父母然后再传递回祖父母的孩子

乔·妈妈

我是React的新手,所以我希望我能正确解决这个问题。首先,我有一个名为SearchLocationsScreen的屏幕在该屏幕内,我有一个名为Map的组件,在Map有一个名为LocationMarker的自定义标记组件在与Map组件相同的层次结构级别上,我有一个名为CheckinModal的自定义ModalBox这是一个粗略的图表可以帮助您:

在此处输入图片说明

In SearchLocationsScreen I am getting the location info from an API call. Then I pass those locations down to my Map component. Inside my Map component I pass the information for the markers down to the custom LocationMarker class and populate the map.

The goal is to press on a marker and have the CheckinModal pop up from the bottom and populate it with info from the particular marker that was pressed. To do this, I use the useRef hook and forwardRef hook to pass a reference to the modal down to the LocationMarker class. Here I call ref.current.open() and the modal opens as expected.

The problem is that I can't figure out a way to pass the location info from the marker, back up the hierarchy to the screen and down to the modal to populate the modal with relevant info. Does anyone know how to achieve this? I'm posting the code below to my screen, map component and marker component (styles not included). Thanks in advance for your help.

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>
    );
};

Map.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;
Jo Momma

I figured it out with the help of Alvaro's comment to my main post.

Here is what I did. First, I moved the code that generates the LocationMarkers to the SearchLocationsScreen. I was already accessing the locations needed for those markers on that screen anyway (originally I was then passing those locations down to the Map component and creating them there). In the SearchLocationsScreen I loop through all the locations to generate the LocationMarkers, adding a callback which uses a useReducer hook to store the modal's state. Since they are both on the same level, I can populate the fields for the modal with the correct data from the reducer's state. That callback is passed down to the LocationMarkers. Then in the LocationMarker onPress我调用此方法。一切正常。这是更新的代码:

SearchLocationsScreen

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,
            })
        }
    }

    const modalReducer = (state, action) => {
        console.log("payload: ", action.payload);
        switch (action.type) {
            case 'show_modal':
                return {...state,
                    companyName: action.payload.companyName,
                    companyAddress: action.payload.companyAddress,
                    waitTime: action.payload.waitTime
                };
            default:
                return state;
        }
    };

    const [modalState, dispatch] = useReducer(modalReducer, {
        companyName: "Company Name",
        companyAddress: "123 Elm St",
        waitTime: 0
    });

    const createMarkers = () => {
        let result = [];
        if (locations) {
            for (let i = 0; i < locations.length; i++) {
                result.push(
                    <LocationMarker
                        key={i}
                        id={i}
                        coordinate={locations[i]}
                        title={locations[i].company}
                        waitTime={locations[i].wait ? `${locations[i].wait} minutes` : 'Closed'}
                        onShowModal={() => {
                            dispatch({
                                type: 'show_modal', payload: {
                                    companyName: locations[i].company,
                                    companyAddress: locations[i].address,
                                    waitTime: locations[i].wait,
                                }
                            });
                            modalRef.current.open();
                        }}
                    />
                )
            }
        }
        return result;
    };

    return (
        <View style={{flex: 1}}>

            <Map markers={createMarkers()}/>
            {/*<Map ref={modalRef} markers={...createMarkers()} />*/}

            <SearchBar style={styles.searchBarStyle}/>

            {err ? <View style={styles.errorContainer}><Text
                style={styles.errorMessage}>{err.message}</Text></View> : null}

            <CheckinModal
                ref={modalRef}
                businessName={modalState.companyName}
                address={modalState.companyAddress}
                waitTime={modalState.waitTime}
            />

        </View>
    );
};

地图

const Map = ({markers}, ref) => {

    const {state: {currentLocation}} = useContext(Context);

    return (

        <MapView
            style={styles.map}
            provider={PROVIDER_GOOGLE}
            initialRegion={{
                ...currentLocation.coords,
                latitudeDelta: regions.latDelta,
                longitudeDelta: regions.longDelta
            }}
            showsUserLocation
            >

            {markers ? markers.map((marker, index) => {
                return marker;
            }): null}

        </MapView>
    )
};

export default Map;

检入模式

const CheckinModal = ({businessName, address, waitTime}, ref) => {

    return (
            <ModalBox
                style={styles.modal}
                position={'bottom'}
                backdrop={true}
                ref={ref}
            >
                <Text>Store Name: {businessName}</Text>
                <Text>Store Address: {address}</Text>
                <Text>Wait time: {waitTime} minutes</Text>
            </ModalBox>
    )
};

const forwardModal = React.forwardRef(CheckinModal);
export default forwardModal;

LocationMarker

const LocationMarker = (props) => {

    return (
        <View>
            <Marker
                coordinate={props.coordinate}
                title={props.title}
                id={props.id}
                onPress={() => {
                    props.onShowModal();
                }}
            >
                <Image
                    source={require('../../assets/marker2.png')}
                    style={styles.locationMarker}/>
                <View style={styles.waitContainer}>
                    <Text style={styles.waitText}>{props.waitTime}</Text>
                </View>
            </Marker>

        </View>
    )
};

export default LocationMarker;

有了这个新代码,我不必转发太多引用,而只需转发给CheckinModal即可

如果有人有任何问题,请将其发布在此答案下方,我将尝试尽快回答。感谢大家的帮助。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在React中,孙子可以访问祖父母的属性而无需父母将其传递下来吗?

来自分类Dev

如何在Scss中引用祖父母?

来自分类Dev

如何从Less的子类中向祖父母施加条件

来自分类Dev

如何在jQuery中选择元素的祖父母

来自分类Dev

如何在SQL层次结构上显示祖父母?

来自分类Dev

如何在多代设置中针对祖父母查询inner_hits

来自分类Dev

Rails:如何在ActiveRecord中设置祖父母值(关联)

来自分类Dev

如何在不同时单击其祖父母元素的情况下单击其子元素?

来自分类Dev

如何从子记录集合中获取重要的祖父母记录集合?

来自分类Dev

我如何调用祖父母的构造函数(因为未定义父母的构造函数)?

来自分类Dev

使用react的上下文允许将子组件呈现为父/祖父母/曾祖父母....反模式?

来自分类Dev

如何获得多维数组中一个数组键的父键,祖父母键和祖父母键?

来自分类Dev

在孩子的祖父母或外祖父母中建立父节点。XSL

来自分类Dev

SSIS如何为祖父母容器强制执行结果成功

来自分类Dev

如何通过尚未保存的父关联访问ActiveRecord祖父母关联?

来自分类Dev

SilverStripe 3:如何按祖父母页面对排序数组进行分组

来自分类Dev

Python-如何避免调用祖父母构造函数(多重继承)

来自分类Dev

单击按钮时,如何选择一个按钮并删除该按钮的祖父母div?

来自分类Dev

如何使子div与其动态大小的祖父母一样宽?

来自分类Dev

XPATH:如何选择祖父母的第三个子元素

来自分类Dev

如何使子模型的字段在祖父母模型的范围内唯一?

来自分类Dev

仅当祖父母被删除时,如何触发子对象的:destroy?

来自分类Dev

React JS:祖父母组件的setState方法不会更新孙输入字段onChange事件单击的状态

来自分类Dev

使DIV达到祖父母高度的100%,同时也拉伸祖父母的宽度

来自分类Dev

获取特定孩子的父母和祖父母

来自分类Dev

如何覆盖父类的init方法,并使用super调用祖父母的init,而无需编辑父类?(python 3)

来自分类Dev

Javascript:当用户从树中选择/取消选择节点时,如何保留树结构和祖父母/子关系

来自分类Dev

使用祖父母块

来自分类Dev

访问祖父母的变量

Related 相关文章

  1. 1

    在React中,孙子可以访问祖父母的属性而无需父母将其传递下来吗?

  2. 2

    如何在Scss中引用祖父母?

  3. 3

    如何从Less的子类中向祖父母施加条件

  4. 4

    如何在jQuery中选择元素的祖父母

  5. 5

    如何在SQL层次结构上显示祖父母?

  6. 6

    如何在多代设置中针对祖父母查询inner_hits

  7. 7

    Rails:如何在ActiveRecord中设置祖父母值(关联)

  8. 8

    如何在不同时单击其祖父母元素的情况下单击其子元素?

  9. 9

    如何从子记录集合中获取重要的祖父母记录集合?

  10. 10

    我如何调用祖父母的构造函数(因为未定义父母的构造函数)?

  11. 11

    使用react的上下文允许将子组件呈现为父/祖父母/曾祖父母....反模式?

  12. 12

    如何获得多维数组中一个数组键的父键,祖父母键和祖父母键?

  13. 13

    在孩子的祖父母或外祖父母中建立父节点。XSL

  14. 14

    SSIS如何为祖父母容器强制执行结果成功

  15. 15

    如何通过尚未保存的父关联访问ActiveRecord祖父母关联?

  16. 16

    SilverStripe 3:如何按祖父母页面对排序数组进行分组

  17. 17

    Python-如何避免调用祖父母构造函数(多重继承)

  18. 18

    单击按钮时,如何选择一个按钮并删除该按钮的祖父母div?

  19. 19

    如何使子div与其动态大小的祖父母一样宽?

  20. 20

    XPATH:如何选择祖父母的第三个子元素

  21. 21

    如何使子模型的字段在祖父母模型的范围内唯一?

  22. 22

    仅当祖父母被删除时,如何触发子对象的:destroy?

  23. 23

    React JS:祖父母组件的setState方法不会更新孙输入字段onChange事件单击的状态

  24. 24

    使DIV达到祖父母高度的100%,同时也拉伸祖父母的宽度

  25. 25

    获取特定孩子的父母和祖父母

  26. 26

    如何覆盖父类的init方法,并使用super调用祖父母的init,而无需编辑父类?(python 3)

  27. 27

    Javascript:当用户从树中选择/取消选择节点时,如何保留树结构和祖父母/子关系

  28. 28

    使用祖父母块

  29. 29

    访问祖父母的变量

热门标签

归档