RN点击事件传递父组件/抽离子组件 2种实现方式

发布时间:2024年01月18日

//第一种实现方式通过pros传递

//TsExample

import IconMore from '@/assets/iconfont/IconMore';

import { $fontSize16, $fontWeight, $row } from '@/styles/commonStyles';

import * as React from 'react';

import {

? StyleSheet,

? View,

? Text,

? ViewProps,

? TouchableHighlight,

} from 'react-native';

type TsExampleProps = {

? text?: string; // 右侧文字

? onBack?: () => void; // 自定义会调 点击backIcon 图标触发

? centerClick?: () => void; // 点title文字

}

const TsExample: React.FC<TsExampleProps> = (props) => {

? const {

? ? centerClick,

? ? onBack,

? ? text,

? } = props;

? if (centerClick) {

? ? return <View>

? ? ? <View style={[$row, { justifyContent: 'space-between', alignItems: 'center', marginTop: 16, marginBottom: 16 }]}>

? ? ? ? <Text style={[$fontSize16, $fontWeight, { color: '#505A6B' }]}>{text}</Text>

? ? ? ? <TouchableHighlight onPress={centerClick}>

? ? ? ? ? <IconMore size={30} />

? ? ? ? </TouchableHighlight>

? ? ? </View>

? ? ? <View style={{ height: 1, backgroundColor: '#eee', width: '100%' }} />

? ? </View>

? }

? return <View>

? ? <View style={[$row, { justifyContent: 'space-between', alignItems: 'center', marginTop: 16, marginBottom: 16 }]}>

? ? ? <Text style={[$fontSize16, $fontWeight, { color: '#505A6B' }]}>{text}</Text>

? ? ? <IconMore size={30} />

? ? </View>

? ? <View style={{ height: 1, backgroundColor: '#eee', width: '100%' }} />

? </View>

}

export default TsExample;

//TsExampleProps

import { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native';

export type TsExampleProps = {

? text?: string; // 右侧文字

? onBack?: () => void; // 自定义会调 点击backIcon 图标触发

? centerClick?: () => void; // 点title文字

};


?

//调用

? ? ? ? <TsExample text={'this is child'} centerClick={_languageClick} />

? const _languageClick = () => {

? ? console.log('ssssssssss')

? };

//第二种实现方式?useImperativeHandle/forwardRef

import {Modal, StyleProp, StyleSheet, Text, TouchableOpacity, View, ViewStyle} from 'react-native';

import React, {useEffect, useState, forwardRef, useImperativeHandle, Ref} from 'react';

import {KeyboardAvoidingView} from 'native-base';

interface Props {

? show?: boolean;

? onClose?: () => void;

? isCancelable?: boolean;

? children: React.ReactNode;

? secondDialog?: React.ReactNode;

? style?: StyleProp<ViewStyle>;

? secondDialogStyle?: StyleProp<ViewStyle>;

? layoutStyle?: StyleProp<ViewStyle>;

}

export interface BaseDialogRef {

? showModal: () => void;

? showSecondDialog: () => void;

? hideSecondDialog: () => void;

}

function BaseDialog({show, onClose, isCancelable, children, style, layoutStyle, secondDialog, secondDialogStyle}: Props, ref: Ref<BaseDialogRef>) {

? const [isVisible, setIsVisible] = useState(false);

? const [isShowSecond, setShowSecond] = useState(false);

? const styles = StyleSheet.create({

? ? container: {

? ? ? flex: 1,

? ? ? backgroundColor: 'rgba(149, 157, 165, 0.5)',

? ? },

? ? modalStyle: {

? ? ? width: 386,

? ? ? minHeight: 253,

? ? ? zIndex: 99999,

? ? ? borderRadius: 12,

? ? ? backgroundColor: '#ffffff',

? ? },

? });

? useEffect(() => {

? ? if (show != null) setIsVisible(show);

? }, [show]);

? useImperativeHandle(ref, () => ({

? ? showModal() {

? ? ? setIsVisible(true);

? ? },

? ? showSecondDialog() {

? ? ? console.log('------showSecondDialog-------', !!secondDialog);

? ? ? setShowSecond(true);

? ? },

? ? hideSecondDialog() {

? ? ? setShowSecond(false);

? ? },

? }));

? const closeModal = () => {

? ? setIsVisible(false);

? ? onClose && onClose();

? };

? return (

? ? <Modal transparent={true} visible={isVisible} animationType={'fade'} onRequestClose={closeModal}>

? ? ? <KeyboardAvoidingView behavior={'padding'} style={{flex: 1}}>

? ? ? ? <View style={styles.container}>

? ? ? ? ? <TouchableOpacity

? ? ? ? ? ? style={[{flex: 1, justifyContent: 'center', alignItems: 'center'}, layoutStyle]}

? ? ? ? ? ? activeOpacity={1}

? ? ? ? ? ? onPress={() => {

? ? ? ? ? ? ? if (isCancelable) closeModal();

? ? ? ? ? ? }}>

? ? ? ? ? ? <TouchableOpacity activeOpacity={1} style={[styles.modalStyle, style]}>

? ? ? ? ? ? ? {children}

? ? ? ? ? ? </TouchableOpacity>

? ? ? ? ? </TouchableOpacity>

? ? ? ? ? {isShowSecond && secondDialog ? (

? ? ? ? ? ? <TouchableOpacity

? ? ? ? ? ? ? style={{position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, backgroundColor: '#21242D99', justifyContent: 'center', alignItems: 'center'}}

? ? ? ? ? ? ? onPress={() => setShowSecond(false)}>

? ? ? ? ? ? ? <TouchableOpacity activeOpacity={1} style={[styles.modalStyle, secondDialogStyle]}>

? ? ? ? ? ? ? ? {secondDialog}

? ? ? ? ? ? ? </TouchableOpacity>

? ? ? ? ? ? </TouchableOpacity>

? ? ? ? ? ) : null}

? ? ? ? </View>

? ? ? </KeyboardAvoidingView>

? ? </Modal>

? );

}

export default forwardRef(BaseDialog);

//使用

? const [isVisible, setIsVisible] = React.useState(true);

? ? ? ? <BaseDialog

? ? ? ? ? style={{ alignItems: 'center', width: '80%', minHeight: 150 }}

? ? ? ? ? ref={baseRef}

? ? ? ? ? show={isVisible}

? ? ? ? ? onClose={() => {

? ? ? ? ? ? setIsVisible(false);

? ? ? ? ? }}>

? ? ? ? ? <TouchableHighlight onPress={() => { setIsVisible(false) }}>

? ? ? ? ? ? <View style={{ paddingHorizontal: 12, paddingVertical: 24, minHeight: 105 }}>

? ? ? ? ? ? ? <Text style={[{ fontSize: 18, lineHeight: 25.2, color: '#333', fontWeight: 'bold', textAlign: 'center' }]}>ssss</Text>

? ? ? ? ? ? </View>

? ? ? ? ? </TouchableHighlight>

? ? ? ? ? <View style={{ flexDirection: 'row' }}>

? ? ? ? ? </View>

? ? ? ? </BaseDialog>

文章来源:https://blog.csdn.net/qq_34812958/article/details/135677894
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。