收藏
回答

点击组件内部的按钮可以在页面中跳出弹窗吗?

地址管理页面,引用了 地址列表组件。

现在需要点击组件中的按钮,在页面中跳出弹窗继续操作。需要实现的效果如图:

目前,把popup的相关代码放在组件中,可以实现其效果及功能,但弹窗出现在组件的框架范围内,而不是出现在页面中。(代码在下面)

如果把popup代码写在页面中,点击组件时不会跳出弹窗,组件中的点击操作没有传到页面中,这里的操作可以怎么做吗?组件内的数据传到页面中可以怎么写代码呢?


列表组件代码(AddressItem):

import React, { memo, useCallback, useEffect, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import {
    View,
    Text,
    Image,
    navigateTo,
} from 'remax/wechat';
import request from '@/utils/request'
import { clearSearchBase64Url } from '@/actions/common'
import { connect } from 'react-redux';
import * as utils from '@/utils/common';
import useSysInfo from '../../hooks/sysInfo'
import { Popup } from 'annar';

import styles from './index.css';
import classnames from 'classnames';

const AddressItem = memo(function (props) {
    const {
        delCb,
    } = props;
    const { id, user_id, phone, name, area, address, is_default } = props;
    const [isShowModal, setIsShowModal] = useState(false);
    const [ShowModal, setShowModal] = useState(false);
    const sysInfo = useSysInfo();
    const defaults = parseInt(is_default)
    const getdelUserAddress = useCallback(() => {
        return request({
            url: '/delUserAddress',
            method: 'post',
            data: {
                id: id
            },
            success: function () {
                delCb(id)
                wx.showToast({
                    title: '删除成功',
                    icon: 'success'
                })
            }
        })
    })

    return (
        <View className={styles.have}>
            <View className={styles.addchoose}>
                <Text>{name}</Text><Text>{phone}</Text>
                {
                    (defaults)
                        ? <View className={styles.default}>默认</View>
                        : null
                }
                <View className={styles.details}>{area}{address}</View>
                <Image src='http://dxshy.duxieshe.com/uploads/applet_img/more.png'
                    onTap={() => {
                        setIsShowModal(true)
                    }}
                />
            </View>
            <Popup
                position="bottom"
                open={isShowModal}
                onClose={() => {
                    setIsShowModal(false)
                }}>
                <View style={{ paddingBottom: sysInfo.safeBottomHeight + 'PX' }}>
                    <View className={styles.background}>
                        <View className={styles.operate}
                            style={{ "color": "#000000" }}
                            onTap={() => {
                                navigateTo({
                                    url: '/packagePagesE/address/editadr/index?userId=' + id
                                })
                                setIsShowModal(false)
                            }}
                        >编辑</View>
                        <View className={styles.smaline}></View>
                        <View className={styles.operate}
                            style={{ "color": "#FF0000" }}
                            onTap={() => {
                                setShowModal(true)
                                setIsShowModal(false)
                            }}
                        >删除</View>
                        <View className={styles.larline}></View>
                        <View className={styles.operate}
                            style={{ "color": "#000000" }}
                            onTap={() => {
                                setIsShowModal(false)
                            }}>取消</View>
                    </View>
                </View>
            </Popup>
            <Popup
                open={ShowModal}
                onClose={() => {
                    setShowModal(false)
                }}>
                <View className={styles.Modal}>
                    <View className={styles.wxts}>温馨提示</View>
                    <Text>删除后数据不可恢复,</Text>
                    <Text>确定要删除吗?</Text>
                    <View className={styles.btn}>
                        <View className={styles.left} onTap={() => {
                            setShowModal(false)
                        }}>取消</View>
                        <View className={styles.right} onTap={() => {
                            setShowModal(false)
                            getdelUserAddress()
                        }}>确认删除</View>
                    </View>
                </View>
            </Popup>
        </View>
    )
})
AddressItem.propTypes = {
    id: PropTypes.string.isRequired,
    user_id: PropTypes.string.isRequired,
    phone: PropTypes.string.isRequired,
    name: PropTypes.string.isRequired,
    area: PropTypes.string.isRequired,
    address: PropTypes.string.isRequired,
    is_default: PropTypes.string.isRequired
}
AddressItem.defaultProps = {
    address: ''
}

const mapStateToProps = (state) => {
    const { userInfo } = state.common
    return {
        userInfo
    }
}
const mapDispatchToProps = (dispatch) => {
    return {
        clearSearchBase64Url: () => {
            dispatch(clearSearchBase64Url())
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(AddressItem);


地址管理主页代码(address.js):

import React, { useEffect, memo, useState, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

import {
    View,
    Text,
    Image,
    ScrollView,
    setClipboardData,
    navigateTo,
    showLoading,
    hideLoading,
} from 'remax/wechat';
import { connect } from 'react-redux';
import { Popup } from 'annar';
import Nav from '@/components/nav';
import Tabbar from '@/components/tabbar';
import request from '@/utils/request';
import useSysInfo from '../../../hooks/sysInfo'
import useBackEvent from '@/hooks/navEvent'
import AddressItem from '@/components/addressItem';

import styles from './index.css';
import { getSysConf } from '../../../actions/common';
import { setList, setCollectStatus } from '../../../actions/dynamic'

const Address = function (props) {
    const { currentTab } = props;
    const [refreshTriggered, setRefreshTriggered] = useState(false);
    const [isLoading, setIsLoading] = useState(false);
    const { getSysConf, sysConf, userInfo } = props;
    const [isShowModal, setIsShowModal] = useState(false);
    const [ShowModal, setShowModal] = useState(false);
    const [hasData, setHasData] = useState(true);
    const [list, setList] = useState();
    const [page, setPage] = useState(1);
    const sysInfo = useSysInfo();
    useEffect(() => {
        getSysConf()
    }, [])

    const {
        homeAction,
        backAction
    } = useBackEvent(currentTab);

    // const Cancel = () => {
    //     setShowModal(false)
    //     wx.showToast({
    //         title: '删除成功',
    //         icon: 'success'
    //     })
    // }

    const loadList = useCallback((passPage) => {
        return request({
            url: '/getUserAddressList',
            method: 'get',
            data: {
                page: passPage ? passPage : page,
                limit: 10
            }
        })
    }, [page])

    const init = useCallback(async () => {
        if (isLoading) return;
        const page = 1;
        setPage(page);
        setHasData(true);
        setIsLoading(true);
        const list = await loadList(page);
        setIsLoading(false);
        setPage(prevPage => prevPage + 1);
        setList(list);
        setRefreshTriggered(false)
        if (list.length < 10) {
            setHasData(false);
        }
        console.log('list', list);
    }, [isLoading, page]);

    const loadMore = useCallback(() => {
        if (isLoading) return;
        if (hasData) {
            setIsLoading(true)
            loadList().then(moreData => {
                setList(preList => preList.concat(moreData))
                setPage(prev => prev + 1);
                setIsLoading(false)
            })
        } /* else {
            wx.showToast({
                title: '没有更多了~',
                icon: 'none'
            })
        } */
    }, [page, hasData, isLoading])

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

    useEffect(() => {
        if (isLoading) {
            showLoading({
                title: '加载中',
                mask: true
            })
        } else {
            hideLoading()
        }
    }, [isLoading])

    return (
        sysConf &&
        <View className={styles.personal} style={{ height: sysInfo.safeArea.bottom + 'PX' }}>
            <Nav
                title="地址管理"
                goIndex={homeAction}
                onBack={backAction}
                showLeftFunc={true} />
            <View className={styles.main}>
                <View className={styles.add} onTap={() => {
                    navigateTo({
                        url: '/packagePagesE/address/addadr/index'
                    })
                }}>
                    <Image src='http://dxshy.duxieshe.com/uploads/applet_img/add_green.png' />
                    <Text>添加收货地址</Text>
                </View>
                {
                    (list && list.length > 0) ?
                        <ScrollView
                            className={styles.list}
                            scrollY
                            refresherEnabled
                            refresherTriggered={refreshTriggered}
                            lowerThreshold={60}
                            bindscrolltolower={loadMore}
                            bindrefresherrefresh={() => {
                                setRefreshTriggered(true)
                                init();
                            }}>
                            <View className={styles.have}>
                                <View className={styles.txt}>轻触以选择地址</View>
                                {
                                    list.map((v, i) => {
                                        return (
                                            <AddressItem key={i} {...v} />
                                        )
                                    })
                                }
                            </View>
                        </ScrollView>
                        : Array.isArray(list) ?
                            <View className={styles.none}>
                                <Image src='http://dxshy.duxieshe.com/uploads/applet_img/none_02.png' />
                                <Text>暂无收货地址~</Text>
                            </View>
                            : null
                }
            </View>

                         //弹窗
            {/* <Popup
                position="bottom"
                open={isShowModal}
                onClose={() => {
                    setIsShowModal(false)
                }}
            >
                <View style={{ paddingBottom: sysInfo.safeBottomHeight + 'PX' }}>
                    <View className={styles.background}>
                        <View className={styles.operate}
                            style={{ "color": "#000000" }}
                            onTap={() => {
                                navigateTo({
                                    url: '/packagePagesE/address/editadr/index'
                                })
                                setIsShowModal(false)
                            }}
                        >编辑</View>
                        <View className={styles.smaline}></View>
                        <View className={styles.operate}
                            style={{ "color": "#FF0000" }}
                            onTap={() => {
                                setShowModal(true)
                                setIsShowModal(false)
                            }}
                        >删除</View>
                        <View className={styles.larline}></View>
                        <View className={styles.operate}
                            style={{ "color": "#000000" }}
                            onTap={() => {
                                setIsShowModal(false)
                            }}>取消</View>
                    </View>
                </View>
            </Popup>
            <Popup
                open={ShowModal}
                onClose={() => {
                    setShowModal(false)
                }}>
                <View className={styles.Modal}>
                    <View className={styles.wxts}>温馨提示</View>
                    <Text>删除后数据不可恢复,</Text>
                    <Text>确定要删除吗?</Text>
                    <View className={styles.btn}>
                        <View className={styles.left} onTap={() => {
                            setShowModal(false)
                        }}>取消</View>
                        <View className={styles.right} onTap={() => {
                            Cancel()
                        }}>确认删除</View>
                    </View>
                </View>
            </Popup> */}
        </View >
    )
}
const mapStateToProps = (state) => {
    const { sysConf, userInfo } = state.common;
    return {
        sysConf,
        userInfo
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        getSysConf: (conf) => {
            dispatch(getSysConf(conf))
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Address)

回答关注问题邀请回答
收藏

3 个回答

  • 睡前原谅一切
    睡前原谅一切
    2022-11-10

    wx.chooseAddress()

    2022-11-10
    有用
    回复
  • optimistic
    optimistic
    2022-11-09

    用的Taro 就简单了,组件写在页面,点击其他组件 事件传到父组件就可以了

    2022-11-09
    有用
    回复 4
    • 啵啵
      啵啵
      2022-11-09
      我不了解Taro
      2022-11-09
      回复
    • optimistic
      optimistic
      2022-11-11回复啵啵
      看错了 你这和taro很像,和框架没关系,这就是 简单的 react 子组件触发父组件问题
      2022-11-11
      回复
    • 啵啵
      啵啵
      2022-11-11回复optimistic
      昂,目前解决这个问题了,谢谢啊
      2022-11-11
      回复
    • K
      K
      01-19回复啵啵
      请问怎么解决的
      01-19
      回复
  • ⅴ
    2022-11-09

    看起来是子组件向父组件传值的问题。

    1.父组件里写弹窗的函数,比如说 showModal()

    2.子组件里调用 this.props.showModal(data),把数据传过去。

    2022-11-09
    有用
    回复 36
    • 啵啵
      啵啵
      2022-11-09
      那popup的代码是放在页面中吗?
      2022-11-09
      回复
    • ⅴ
      2022-11-09回复啵啵
      popup是指弹窗吗?弹窗的动作和html放在父页面,数据通过子组件传过去。
      2022-11-09
      回复
    • 啵啵
      啵啵
      2022-11-09
      popup是弹窗。代码这样改?showModal()函数要怎么写?像图里面的红圈这样改吗?现在这样写有一个报错
      2022-11-09
      回复
    • ⅴ
      2022-11-09回复啵啵
      子组件也写一个function,里面是this.props.showModal,然后html里绑定。
      2022-11-09
      回复
    • ⅴ
      2022-11-09回复
      先确认一下,子组件数据有没有传过来
      showModal(data){
          console.log('获取子组件数据',data)

          setIsShowModal(true)
      }
      2022-11-09
      回复
    查看更多(31)
登录 后发表内容