如何修改React-Native组件的默认属性?

1,097 阅读3分钟

作者:iplaycodex
仓库:githubcodePen
博客:掘金segmentfault知乎简书博客园leetcode
公众号:FEZONE
联系我:iplaycodex@163.com
特别声明:原创不易,未经授权不得对此文章进行转载或抄袭,否则按侵权处理,如需转载或开通公众号白名单可联系我,尊重原创尊重知识产权从我做起

1. 问题

我们在做网页开发的时候知道标签有自己的默认样式,例如<ul/>,<li/>等等.所以一般我们在开发项目的时候首先要做的就是先把标签的默认样式给清除掉.例如使用reset.css || normalize.css.在开发 RN 的时候发现有些组件的默认属性很烦人.同样的需要重写这些默认属性.例如:

<Text /> <TextInput />

这两个组件的allowFontScaling=true即:属性默认跟随系统字体大小,超级坑爹.

还有这个组件:

<TouchableOpacity />

这个组件默认点击的时候会有一个阴影效果,因为它的默认透明度是0.2.

这些默认属性有时候会给我们带来很大的困扰,有些组件的属性默认值并不是我们想要的.那么该怎么做呢?在每次使用这个组件的时候手动修改该组件的属性值?

这样做可以满足需求,但是太蠢了.每次使用上述组件的时候都要修改某些属性值.太蠢.这个方法舍弃.

2. 解决之道:

下面以 Text 组件为抓手,探究一下这个问题的根源和解决之道

既然我们知道了导致问题的所在原因,那么就着手解决掉就可以了.经过查react-native的官方文档得知:在react-native中用来显示文字的,一般会用到两个组件:TextTextInput。所以,我们只要针对这两个组件做好工作,那就基本上解决了字体大小适配的问题

而他们两个有个共同的属性allowFontScaling,这个属性的值模式是true,这个属性是什么意思呢?

是否随系统指定的文字大小变化而变化。默认值为 true

2.1. 解决方法一:设置allowFontScaling属性为false

// 设置该属性为false
<Text allowFontScaling="{false}" />
<TextInput allowFontScaling="{false}" />

但是这个方法有个弊端,也就是说在每次使用Text,TextInput组件的时候都要设置这个属性为false,有点麻烦,万一那次不小心忘了.就又炸了.

2.2. 解决方法二:封装原生TextTextInput组件

每次使用Text或者TextInput组件的时候都要设置这个属性为false好烦,那么我们不禁会想到自己封装一个公共组件,如下所示:

import React from "react";
import { Text } from "react-native";

export default class MyText extends React.Component {
    // 封装react-native原生组件为MyText
    render() {
        return (
            <Text allowFontScaling={false} {...this.props}>
                {this.props.children}
            </Text>
        );
    }
}

TextInput 组件同理

这样每次在使用Text组件的时候就使用封装好的MyText就行了,这个问题也就解决了.但是,这不是更麻烦吗?每次使用的时候还需要导入这个组件,万一忘了就又炸了!这个方案 PASS!

2.3. 解决方案三:修改组件的defaultProps

翻看一下组件的源码:

TextInput

...
  getDefaultProps(): Object {
    return {
      allowFontScaling: true,
      underlineColorAndroid: 'transparent',
    };
  },
...

Text

...
  static defaultProps = {
    accessible: true,
    allowFontScaling: true,
    ellipsizeMode: 'tail',
  };
...

通过这两个代码片段可以知道,在定义 Text 和 TextInput 时,都有给组件设置默认属性的操作.那么就有解决方案就有了:

TextInput.defaultProps = Object.assign({}, TextInput.defaultProps, {
    defaultProps: false,
});
Text.defaultProps = Object.assign({}, Text.defaultProps, {
    allowFontScaling: false,
});
TouchableOpacity.defaultProps = Object.assign(
    {},
    TouchableOpacity.defaultProps,
    { activeOpacity: 1 }
);

切记这段代码要写在你react-native的入口处,我写在了index.js里面.使用该方法真正实现了一劳永逸,所以这个方法是最方便的.

3. 结束语

❤️ 关注 + 点赞 + 收藏 + 评论 + 转发 ❤️
原创不易,鼓励笔者创作更好的文章~