React Native之加载顺序导致的奇怪问题

663 阅读2分钟

问题

今天在写一个自定义组件,有两个defaultProps

static defaultProps = {
      locked: true,
      headerComponent: (
          <View>
              <Text>1234</Text>
          </View>
      ),
      renderTabBar:(activeTab,goToPage)=>{
          return (
              <View style={{height:80,flexDirection:'row'}}>
                  <TouchableOpacity
                      activeOpacity={1}
                      onPress={()=>{
                          goToPage(0);
                      }}
                      style={{flex:1,justifyContent:'center',alignItems:"center",backgroundColor:activeTab==0?'red':'gray'}}>
                      <Text style={{fontSize:25,fontWeight:'bold'}}>Tab 1</Text>
                  </TouchableOpacity>
              </View>
          );
      }
}

在项目入口处是有设置全局禁止字体放大的(iOS和android在系统设置都可以设置全局的字体大小,默认app是会受其影响的,如果设置allowFontScaling=false可以不受系统影响)

const App = require('./pages/app').default;
//所有的路由文件
const AppNav = require('./pages/appNav').default;

const AppWidthNavigator = createAppContainer(AppNav);
const AppWitheNavigationState = (<App  AppNavigator={AppWidthNavigator}/>);

...

class Root extends Component<any,any> {
  constructor(props) {
    super(props);
    //全局设置 禁止APP受系统字体放大缩小影响
    // @ts-ignore
    Text.defaultProps={...(Text.defaultProps||{}),allowFontScaling:false};
  }
  
  render() {
    return (
      <View style={{flex: 1}}>
        <Provider store={store}>
          {AppWitheNavigationState}
        </Provider>
      </View>
    );
  }
}

照理说,上面的代码,可以全局影响,但是实际上 renderTabBar方法受影响了,但是headerComponent不受影响,两者的区别是前者是组件,后者是方法

结论

最开始怀疑是全局设置allowFontScaling无效的问题(以前不同的RN版本更改过该处),发现这样使用没关系,怀疑是加载顺序的问题

AppNav该文件加载了所有的路由文件,该文件的初始化在设置allowFontScaling之前,对于直接返回组件的这种defaultProps,allowFontScaling的设置自然无效了

将appNav的加载放置在root组件的constructor方法之后即可

root.tsx修改为:

const App = require('./pages/app').default;

...

class Root extends Component<any,any> {
  constructor(props) {
    super(props);
    //全局设置 禁止APP受系统字体放大缩小影响
    // @ts-ignore
    Text.defaultProps={...(Text.defaultProps||{}),allowFontScaling:false};
  }
  
  render() {
    return (
      <View style={{flex: 1}}>
        <Provider store={store}>
          <App  AppNavigator={createAppContainer(require('./pages/appNav').default)}/>
        </Provider>
      </View>
    );
  }
}