Closed seenyea closed 2 years ago
@seenyea I can, but what is the motivation behind it?
Optimized component already do isCached(name)
checks. And if component was found in cache, it will mount it in sync way.
If you need to have multiple references to this component, then you can simply create index.js
file and put register function there. And import this file everywhere you want. Once first usage will be loaded all others will automatically use cached version.
Did I answer on your question?
can I add it myslef?
@seenyea yes, you can. You can simply import necessary functions into your code and re-create this function in your codebase. But why? The code above doesn't make any sense and I don't see any reasons to use it. OptimizedComponent
already use if(isCached(name))
checks. And if component found in cache it will immediately render it.
If you need to have multiple usage of one component, then you can create index.js
file and register your component there:
// index.js
export default register({
require: () => require("./View"),
name: "Tab"
});
And import this file where you want. If it has multiple usages - you can add several import statements. This component will not be loaded until you start using it (until it will be really displayed). Once one usage of this component will be loaded - all others will use it from cache.
Does it make sense?
for react native v3 I crate a TopTabNavigator lib.js
function createTopTabNavigator(
routeConfigMap: NavigationRouteConfigMap,
drawConfig?: DUTabNavigatorConfig
)
view.js
const routeConfigMap = {...};
const drawConfig = {...}
const tab = createTopTabNavigator(routeConfigMap, drawConfig);
class Page extends React.Component{
static router = tab.router
render(){
return <div>test</div>
}
}
index.js
register({
require: () => require('./view'),
static: {
navigationOptions: ({ navigation }) => {
console.log('recommend => ');
return {title: navigation.getParam('title')};
},
router: //here are I need "tab.router "too, how can I do it?
}
})
for react native v3 I crate a TopTabNavigator lib.js
function createTopTabNavigator( routeConfigMap: NavigationRouteConfigMap, drawConfig?: DUTabNavigatorConfig ) view.js
const routeConfigMap = {...}; const drawConfig = {...} const tab = createTopTabNavigator(routeConfigMap, drawConfig); class Page extends React.Component{ static router = tab.router render(){ return
register({ require: () => require('./view'), static: { navigationOptions: ({ navigation }) => { console.log('recommend => '); return {title: navigation.getParam('title')}; }, router: //here are I need "tab.router "too, how can I do it } })
if I have two pages: page1 and page2 as below: page1.js
import Test from './index.js'
page2.js
import Test from './index.js'
what happen?
throw an error: You try to add new component with already existing name: xxxx
can you give me some advices?
I try this way:
import { register, isCached, preload } from 'react-native-bundle-splitter';
const compName = 'RecTab';
const RecTab = isCached(compName) ? preload().component(compName) : register({
require: () => require('./view'),
name: compName,
static: {
navigationOptions: ({ navigation }) => {
console.log('recommend => ');
return {title: navigation.getParam('title')};
}
}
});
export default RecTab;
but the error still look at me, can you give some advice?
@seenyea
here are I need "tab.router "too, how can I do it?
const routeConfigMap = {...};
const drawConfig = {...}
const tab = createTopTabNavigator(routeConfigMap, drawConfig);
register({
require: () => require('./view'),
static: {
navigationOptions: ({ navigation }) => {
console.log('recommend => ');
return {title: navigation.getParam('title')};
},
router: tab.router,
}
})
But that's strange, that your components are aware about navigators where this component will be used.
I try this way:
That's wrong, because isCached
may return false
several times, and you will attempt to register component several times (and you will see error - it's expected behavior).
For me it seems, that you use API in wrong way. You should call register
only one time for one component. This function will return you react component (react component will return null
from render, when component isn't loaded and will return component, when it will be loaded).
You should call preload
only when you know, that this component will be soon displayed (for example user passed Login screen -> you can call preload().component('Dashboard')
because this screen will be visible after login).
You shouldn't use isCached
in your code at all. I exported this function in order to gave a control for developers over information about what is located in cache.
It's hard to gather all information from small samples of code. If it's possible, please, create small reproducible demo with your issue/bug. Thanks in advance!
sorry about it,
createTopTabNavigator
is the same as createMaterialTopTabNavigator
you can find document here https://reactnavigation.org/docs/3.x/material-top-tab-navigator
I think preload().component
is an async way, can get a sync way?
I think preload().component is an async way, can get a sync way?
It's I/O operation. It should be async
.
createTopTabNavigator is the same as createMaterialTopTabNavigator
Are you trying to make lazy tab bars? I mean you are trying to make entire container lazy, not separate screens, right?
The most confusing part of app for me is:
static router = tab.router
I used many times tab navigators in different versions and I haven't extracted any properties from that like you do. Can you explain why you do it? You can simply attach a link, where I can read about it.
Are you trying to make lazy tab bars? I mean you are trying to make entire container lazy, not separate screens, right? yes, any idea for me.
Can you explain why you do it?
now I rewrite an old project(enhance performance), all the tabs use same function createTopTabNavigator
which custom tabBarComponent
, then return React.component
which has a static prop router
.
In register
api, I need rewrite static props as your document statement, how can rewrite createTopTabNavigator
code like this(lot of pages use createTopTabNavigator
):
import React, {Component} from 'react';
import {Animated, View, StyleSheet, Dimensions} from 'react-native';
import {
createMaterialTopTabNavigator,
MaterialTopTabBar,
NavigationRouteConfigMap,
TabNavigatorConfig
} from "react-navigation";
import PropTypes from "prop-types";
const screenWidth = Dimensions.get('window').width;
export type DUTopTabNavigatorProps = {
setBadge: (index: { show: boolean, count: number }) => void
};
export interface DUTabNavigatorConfig extends TabNavigatorConfig{
badgeStyle?: PropTypes;
}
function createTopTabNavigator(
routeConfigMap: NavigationRouteConfigMap,
drawConfig?: DUTabNavigatorConfig
): React.Component {
const {tabNum =4} = drawConfig || {};
class TabBar extends MaterialTopTabBar {
....
}
const config = Object.assign({
tabBarComponent: TabBar,
tabBarOptions: {
...
},
....
}, drawConfig || {});
const TabNavigator = createMaterialTopTabNavigator(
routeConfigMap,
config);
class Page extends Component {
static router = TabNavigator.router;
constructor(props) {
super(props);
this.state = {
badge: {}
};
}
componentDidAppear() {
}
render() {
return <TabNavigator navigation={this.props.navigation} screenProps={{badge: this.state.badge}}/>
}
}
return Page;
}
const styles = StyleSheet.create({
label: {
textAlign: 'center',
fontSize: 13,
margin: 8,
backgroundColor: 'transparent',
}
});
export {createTopTabNavigator};
Hi @seenyea
You can not make entire tab bar lazy in react-navigation v3. I gave detailed answer on that in this comment. Unfortunately it's a restriction of react-navigation <= v4.
I would recommend you to wrap separate screens into register
(which are used in TabBar
). In this case everything will work properly and you will not have issues.
Actually, I make it work today. code like this:
common.tab.js
import React from 'react'; import {Animated, View, StyleSheet, Dimensions} from 'react-native';
import { createMaterialTopTabNavigator, MaterialTopTabBar, NavigationRouteConfigMap, TabNavigatorConfig } from "react-navigation";
const screenWidth = Dimensions.get('window').width;
export type DUTopTabNavigatorProps = { setBadge: (index: { show: boolean, count: number }) => void };
export interface DUTabNavigatorConfig extends TabNavigatorConfig{ badgeStyle?: PropTypes; }
const tabRoute = {};//cache the tab route;
function createTopTabNavigator( routeConfigMap: NavigationRouteConfigMap, drawConfig?: DUTabNavigatorConfig, name: '' ): React.Component { const {tabNum =4} = drawConfig || {};
class TabBar extends MaterialTopTabBar { }
const config = Object.assign({ tabBarComponent: TabBar, ... }, drawConfig || {});
const TabNavigator = tabRoute[name] || createMaterialTopTabNavigator( routeConfigMap, config);
tabRoute[name] = TabNavigator;
return TabNavigator; }
const styles = StyleSheet.create({ label: { textAlign: 'center', fontSize: 13, margin: 8, backgroundColor: 'transparent', } });
export {createTopTabNavigator};
> ***HomeTab.js***
import React from 'react'; import {Dimensions} from 'react-native'; import px2dp from '../../utils/px2dp'; import { createTopTabNavigator } from './common.tab.js';
export const HomeTab = createTopTabNavigator( { ... }, { ... }, 'homeNavi' );
> ***Home.js***
import React from 'react'; ... import { register, getComponent, isCached } from '../../utils/split'; import { HomeTab } from './HomeTab';
const name = 'Home'; const staticProps = { navigationOptions: ({ navigation }) => { return { ... } }, router: HomeTab.router };
const BundleComponent = isCached(name) ? getComponent(name) : register({ require: () => require('./HomeView'), name, static: {...staticProps} });
export default BundleComponent;
> ***HomeTab.js***
import React from 'react'; import { HomeTab } from './HomeTab';
@screen('Home') class Home extends React.Component{
constructor(props) {
super(props);
....
}
componentDidMount() {
...
}
render() {
return <HomeTab navigation={this.props.navigation} screenProps={{badge: 0}}/>
}
}
export default Home;
@seenyea why HomeView
needs to know anything about router
?
why HomeView needs to know anything about router?
I'm not sure router
is needed for HomeView
.
It is generated by createMaterialTopTabNavigator
, so I do not ignore it.
do you have any idea for this?
@seenyea no, I don't have any ideas why it's needed. And also I can not find any information about it in documentation. If you remove it - will app work without it?
Closed due to the inactivity.
物流页面need test
Is your feature request related to a problem? Please describe. can override register api: the complie method
my override