前言:最近工作刚刚接手React项目,封装一个组件是学习React中最基础的一个部分,那么让我们动手来写一个简单的React组件吧!
1.interface接口定义
首先来看我们要实现的组件效果,如图所示,这是一个简单的展示视频速率的小组件:
你可以给它设置各种各样的样式,比如经典的深色模式或浅色模式等。
那么它都有哪些属性呢?让我们来看一下 interface.ts 文件:
import { TextStyle, ViewStyle } from 'react-native';
export interface VideoBitProps {
// 容器样式
containerStyle: ViewStyle;
// 文字背景样式
bitTxtBoxStyle: ViewStyle;
// 速率单位样式
unitStyle: TextStyle;
// 速率样式
valueStyle: TextStyle;
// 速率(自定义)
bitValue: string | undefined;
// 速率单位
unit: string;
}
复制代码
主要定义了组件的如下属性:
字段 | 说明 | 类型 | 默认值 |
---|---|---|---|
unit | 速率单位 | string | kb/s |
bitValue | 速率(自定义) | string | undefined |
valueStyle | 速率样式 | TextStyle | {} |
unitStyle | 速率单位样式 | TextStyle | {} |
bitTxtBoxStyle | 文字背景样式 | ViewStyle | {} |
containerStyle | 容器样式 | ViewStyle | {} |
2.组件实现部分
先来看下整体的代码模块:
index.tsx文件
import React, { useState, useEffect } from 'react';
import _ from 'lodash';
import { View, Text } from 'react-native';
import Styles from './style';
import TYIpcPlayerManager from '../ty-ipc-native';
import { VideoBitProps } from './interface'
const VideoBit: React.FC<VideoBitProps> & {
defaultProps: Partial<VideoBitProps>;
} = props => {
const [bitRateValue, setBitRateValue] = useState('');
const { containerStyle, bitTxtBoxStyle, valueStyle, unitStyle, bitValue, unit } = props;
let timer = null;
useEffect(() => {
convertBitRate();
return () => {
clearInterval(timer);
};
}, []);
const convertBitRate = () => {
getBitValue();
timer = setInterval(() => {
getBitValue();
}, 3000);
};
const getBitValue = () => {
TYIpcPlayerManager.getVideoBitRateKBPS()
.then(data => {
if (data) {
const realBit = (+data).toFixed(0);
setBitRateValue(realBit);
}
})
.catch(err => {
clearInterval(timer);
});
};
return (
<View style={[Styles.videoBitContainer, containerStyle]}>
{(bitRateValue !== undefined) || (bitValue !== undefined ) ? (
<View style={[Styles.bitTxtBox, bitTxtBoxStyle]}>
<Text style={[Styles.fontContainer, valueStyle]}>
{bitRateValue || bitValue}{` `}
<Text style={[Styles.fontContainer, unitStyle]}>{unit}</Text>
</Text>
</View>
) : null}
</View>
);
};
VideoBit.defaultProps = {
containerStyle: {},
bitTxtBoxStyle: {},
valueStyle: {},
unitStyle: {},
unit: 'kb/s',
bitValue: undefined,
};
export default VideoBit;
复制代码
3.组件使用实例
const NormalTopRight = () => {
return (
<VideoBit
bitValue="20"
unit="m/s"
unitStyle={{ color: 'black' }}
containerStyle={{ position: 'absolute', left: 20, top: 50 }}
/>
);
};
复制代码
4.单元测试
VideoBit.test.ts 文件:
import React from 'react';
import { shallow } from 'enzyme';
import VideoBit from '../index';
describe('VideoBit components', () => {
it('basic render', () => {
const wrapper = shallow(
<VideoBit containerStyle={{ position: 'absolute', right: 0, top: 30 }} />
);
expect(wrapper).toMatchSnapshot();
});
it('container render', () => {
const wrapper = shallow(<VideoBit valueStyle={{ color: 'red', fontSize: 24 }} />);
expect(wrapper).toMatchSnapshot();
});
it('bitTxtBox render', () => {
const wrapper = shallow(<VideoBit bitTxtBoxStyle={{ width: 100, height: 30 }} />);
expect(wrapper).toMatchSnapshot();
});
it('unit render', () => {
const wrapper = shallow(<VideoBit unitStyle={{ color: 'black' }} />);
expect(wrapper).toMatchSnapshot();
});
it('bit data', () => {
const wrapper = shallow(<VideoBit bitValue={30} />);
expect(wrapper).toMatchSnapshot();
});
it('unit data', () => {
const wrapper = shallow(<VideoBit unit="m/s" />);
expect(wrapper).toMatchSnapshot();
});
});
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END