React组件概念想必大家都熟悉了,但是在业务开发过程中,面对通用的业务,怎么编写一个通用的React业务组件呢?本文以实际案例说明,如何编写一个通用的业务组件。
实现一个如图所示的组件,可以添加对组件进行添加和删除
实现上面的界面展示,需要三个方面的东西
import React, { Component } from 'react';
import {Input, Icon} from 'antd';
import PropTypes from 'prop-types';
class List extends Component{
render() {
let iconStyle = {
del: {
color: 'red', marginLeft: '0.2%'
},
add: {
color: 'grey', marginLeft: '0.2%'
}
}
return
}
}
上面就把基本的样式搞定了,这离我们想要的还缺一些基本的功能
组件处于编辑状态的时候
class List extends Component{
constructor(props) {
super(props);
this.state = {
list : [1]
}
}
add = (key) => () => {
let list = this.state.list;
list.push(1);
this.setState({
list: list
});
}
del = (key) => () => {
let list = this.state.list;
list.splice(key, 1, 0);
this.setState({
list: list
});
}
renderList = () => {
let list = this.state.list;
let renderList = [];
let len = list.length;
let delShow = list.reduce((total, value) => total + value);
let iconStyle = {
del: {
color: 'red', marginLeft: '0.2%'
},
add: {
color: 'grey', marginLeft: '0.2%'
}
}
for (let i =0; i < len; i++) {
list[i] && renderList.push(
{delShow > 1 && }
)
}
return renderList;
}
render() {
return this.renderList();
}
}
实现了上述组件,可以进行添加和删除了,但是这个组件具备一个完整的组件还需要一些功能
class List extends Component{
constructor(props) {
super(props);
this.state = {
list : [1]
}
}
static defaultProps = {
iconStyle: {
del: {
color: 'red', marginLeft: '0.2%'
},
add: {
color: 'grey', marginLeft: '0.2%'
}
},
// 提供默认的样式选择
layoutStyle: {
display: 'flex',
width: '40%',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start'
},
// 通过disabled控制组件的状态
disabled: false
}
add = (key) => () => {
let list = this.state.list;
list.push(1);
this.setState({
list: list
});
}
del = (key) => () => {
let list = this.state.list;
list.splice(key, 1, 0);
this.setState({
list: list
});
// console.log('exce del action', key);
}
// 获取组件的值,本文中默认所有组件都实现getValue方法,然后通过ref方法获得
getValue = () => {
let list = this.state.list;
let len = list.length;
let value = [];
for(let i = 0; i< len; i++) {
if(list[i]) {
value.push(this.refs[i].getValue())
}
}
return value;
}
renderList = (value) => {
let list = this.state.list;
let renderList = [];
let len = list.length;
let delShow = list.reduce((total, value) => total + value);
let { iconStyle, disabled} = this.props;
for (let i =0; i < len; i++) {
list[i] && renderList.push(
{!disabled && delShow > 1 && }
{!disabled && }
)
}
return renderList;
}
render() {
let { value, layoutStyle } = this.props;
return
// 通过value设置组件的默认值
{this.renderList(value)}
}
}
经过上面的编写,终于完成了组件的基本样式和功能,基本上是够用的了,但是组件还存在一些问题,通用性不够。
class List extends Component{
constructor(props) {
super(props);
this.state = {
list : [1]
}
}
static defaultProps = {
iconStyle: {
del: {
color: 'red', marginLeft: '0.2%'
},
add: {
color: 'grey', marginLeft: '0.2%'
}
},
layoutStyle: {
display: 'flex',
width: '40%',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start'
},
disabled: false
}
add = (key) => () => {
let list = this.state.list;
list.push(1);
this.setState({
list: list
});
}
del = (key) => () => {
let list = this.state.list;
list.splice(key, 1, 0);
this.setState({
list: list
});
// console.log('exce del action', key);
}
getValue = () => {
let list = this.state.list;
let len = list.length;
let value = [];
for(let i = 0; i< len; i++) {
if(list[i]) {
value.push(this.refs[i].getValue())
}
}
return value;
}
renderList = (value) => {
let list = this.state.list;
let renderList = [];
let len = list.length;
let delShow = list.reduce((total, value) => total + value);
// InputComponent 就是你的输入组件 ,after则是你需要插入的后缀组件
let { iconStyle, disabled, InputComponent, after} = this.props;
for (let i =0; i < len; i++) {
list[i] && renderList.push(
{delShow > 1 && after}
{!disabled && delShow > 1 && }
{!disabled && }
)
}
return renderList;
}
render() {
let { value, layoutStyle } = this.props;
return
{this.renderList(value)}
}
}
至此,整个功能就编写完成了。
那么还缺一点东西,那就是参数说明
List.propTypes = {
value: PropTypes.array,
layoutStyle: PropTypes.object,
iconStyle: PropTypes.object,
InputComponent: PropTypes.element.isRequired,
after: PropTypes.node,
disabled: PropTypes.bool
};
附上完整代码
import React, { Component } from 'react';
import {Input, Icon} from 'antd';
import PropTypes from 'prop-types';
class List extends Component{
constructor(props) {
super(props);
this.state = {
list : [1]
}
}
static defaultProps = {
iconStyle: {
del: {
color: 'red', marginLeft: '0.2%'
},
add: {
color: 'grey', marginLeft: '0.2%'
}
},
layoutStyle: {
display: 'flex',
width: '40%',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'flex-start'
},
disabled: false
}
add = (key) => () => {
let list = this.state.list;
list.push(1);
this.setState({
list: list
});
}
del = (key) => () => {
let list = this.state.list;
list.splice(key, 1, 0);
this.setState({
list: list
});
// console.log('exce del action', key);
}
getValue = () => {
let list = this.state.list;
let len = list.length;
let value = [];
for(let i = 0; i< len; i++) {
if(list[i]) {
value.push(this.refs[i].getValue())
}
}
return value;
}
renderList = (value) => {
let list = this.state.list;
let renderList = [];
let len = list.length;
let delShow = list.reduce((total, value) => total + value);
let { iconStyle, disabled, InputComponent, after} = this.props;
for (let i =0; i < len; i++) {
list[i] && renderList.push(
{/* */}
{delShow > 1 && after}
{!disabled && delShow > 1 && }
{!disabled && }
)
}
return renderList;
}
render() {
let { value, layoutStyle } = this.props;
return
{this.renderList(value)}
}
}
List.propTypes = {
value: PropTypes.array,
layoutStyle: PropTypes.object,
iconStyle: PropTypes.object,
InputComponent: PropTypes.element.isRequired,
after: PropTypes.node,
disabled: PropTypes.bool
};
export default List;