feat: impl onAppear and onDisappear

This commit is contained in:
ZeroLing 2022-06-06 21:46:48 +08:00 committed by ClarkXia
parent 8aa8764d06
commit 68fdcf8bc0
9 changed files with 131 additions and 10 deletions

View File

@ -17,5 +17,7 @@ export default defineConfig({
},
dropLogLevel: 'warn',
plugins: [pluginAuth(), pluginRaxCompat()],
eslint: true,
});
// eslint: true,
ssr: false,
ssg: false,
});

View File

@ -14,7 +14,10 @@
"@ice/plugin-rax-compat": "workspace:*",
"@ice/runtime": "workspace:*",
"ahooks": "^3.3.8",
"rax-image": "^2.4.1",
"rax-is-valid-element": "^1.0.0",
"rax-text": "^2.2.0",
"rax-view": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},

View File

@ -0,0 +1,10 @@
import { createElement } from 'rax';
import Image from 'rax-image';
import styles from './index.module.css';
export default (props) => {
const { uri } = props;
const source = { uri };
return <Image className={styles.logo} source={source} />;
};

View File

@ -0,0 +1,5 @@
.logo {
width: 200rpx;
height: 180rpx;
margin-bottom: 20rpx;
}

View File

@ -5,4 +5,21 @@
.data {
margin-top: 10px;
}
}
.homeContainer {
align-items: center;
margin-top: 200rpx;
}
.homeTitle {
font-size: 45rpx;
font-weight: bold;
margin: 20rpx 0;
}
.homeInfo {
font-size: 36rpx;
margin: 8rpx 0;
color: #555;
}

View File

@ -0,0 +1,18 @@
import { createElement, forwardRef, createRef, useRef } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import styles from './index.module.css';
import Logo from '@/components/Logo';
export default function Home() {
return (
<View className={styles.homeContainer} onAppear={() => { console.log('view appear'); }}>
<Logo uri="//gw.alicdn.com/tfs/TB1MRC_cvb2gK0jSZK9XXaEgFXa-1701-1535.png" />
<Text className={styles.homeTitle}>Welcome to Your Rax App</Text>
<Text className={styles.homeInfo}>More information about Rax</Text>
<Text className={styles.homeInfo}>Visit https://rax.js.org</Text>
</View>
);
}

View File

@ -45,7 +45,8 @@
"compat"
],
"dependencies": {
"@swc/helpers": "^0.3.8"
"@swc/helpers": "^0.3.8",
"appear-polyfill": "^0.1.2"
},
"devDependencies": {
"@ice/pkg": "^1.0.0-rc.0",

View File

@ -1,4 +1,22 @@
import React from 'react';
import React, {
Attributes,
FunctionComponent,
ReactElement,
ReactNode,
RefObject,
useEffect, useRef, forwardRef,
} from 'react';
import { isFunction } from './type';
// @ts-ignore
import { setupAppear } from 'appear-polyfill';
let appearSetup = false;
function setupAppearOnce() {
if (!appearSetup) {
setupAppear();
appearSetup = true;
}
}
/**
* Compat createElement for rax export.
@ -6,9 +24,56 @@ import React from 'react';
* @param type
* @param props
* @param children
* @param others
* @returns Element
*/
export function createElement(type: any, props: Object, children: any, ...others: any) {
return React.createElement(type, props, children, ...others);
export function createElement<P extends {
ref: RefObject<any>;
children: any; onAppear?: Function;
onDisappear?: Function;
}>(
type: FunctionComponent<P>,
props?: Attributes & P | null,
...children: ReactNode[]): ReactElement {
const { children: propsChildren, onAppear, onDisappear, ...rest } = props;
rest.ref = props.ref || useRef(null);
let element: any = React.createElement(type, rest as Attributes & P | null, propsChildren, ...children);
// Polyfill onAppear and onDisappear.
if (isFunction(onAppear) || isFunction(onDisappear)) {
setupAppearOnce();
element = React.createElement(forwardRef(AppearOrDisappear), {
onAppear: onAppear,
onDisappear: onDisappear,
ref: rest.ref,
}, element);
}
return element;
}
// Appear HOC Component.
function AppearOrDisappear(props: any, ref: RefObject<EventTarget>) {
const { onAppear, onDisappear } = props;
listen('appear', onAppear);
listen('disappear', onDisappear);
function listen(eventName: string, handler: EventListenerOrEventListenerObject) {
if (isFunction(handler) && ref != null) {
useEffect(() => {
const { current } = ref;
if (current != null) {
current.addEventListener(eventName, handler);
}
return () => {
const { current } = ref;
if (current) {
current.removeEventListener(eventName, handler);
}
};
}, [ref, handler]);
}
}
return props.children;
}

View File

@ -65,7 +65,7 @@ export async function loadRoutesData(
matches.map(async (match) => {
const { id } = match.route;
const routeModule = routeModules[id];
const { getData } = routeModule;
const { getData } = routeModule ?? {};
if (getData) {
routesData[id] = await getData(requestContext);
@ -195,4 +195,4 @@ export function filterMatchesToLoad(prevMatches: RouteMatch[], currentMatches: R
return currentMatches.filter((match, index) => {
return isNew(match, index) || matchPathChanged(match, index);
});
}
}