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

文章介绍了在ReactNative中,通过pros传递和useImperativeHandle/forwardRef两种方法来实现组件的可定制交互,如自定义点击事件。作者分别展示了如何在TsExample组件中使用这两种技术,并提供了示例代码和调用方式。
摘要由CSDN通过智能技术生成

//第一种实现方式通过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>

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值