mingjun97的blog

日常填坑的各种记录

React踩坑记录1 - 将Const类型的组件改写为Class类型的组件

背景

博主没系统学过JavaScript,但是由于项目需要所以利用Admin-On-Rest框架进行编写程序,该框架基于React,利用JSX进行编写,在编写的时候由于不懂JS所以回踩到很多很多的坑。排坑过程记录一下,方便有其他像我这样强行开车的同学跳坑而出。

修改过程

直接利用Admin-On-Rest-demo魔改的,在一个List中需要添加几个按钮,demo中将该按钮写成了const类型的IconButton,我需要自己添加一些点击后的业务逻辑,所以需要将其修改为Class类型。

旧代码

魔改源代码路径:

1
./admin-on-rest-demo/src/buttons/EditButton.js

魔改源代码内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import IconButton from 'material-ui/IconButton';
import {cyan500} from 'material-ui/styles/colors';
import ContentCreate from 'material-ui/svg-icons/content/create';

const EditButton = ({ basePath = '', record = {} }) => (
<IconButton
containerElement={<Link to={`${basePath}/${record.id}`} />}
style={{ overflow: 'inherit' }}
>
<ContentCreate color={cyan500} />
</IconButton>
);

EditButton.propTypes = {
basePath: PropTypes.string,
record: PropTypes.object,
};

EditButton.defaultProps = {
style: { padding: 0 },
};

export default EditButton;

魔改后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import IconButton from 'material-ui/IconButton';
import { cyan500 } from 'material-ui/styles/colors';
import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet';
import { Dialog, FlatButton, TextField } from 'material-ui';

class TopUpButton extends Component{
constructor(props) {
super(props);
this.state = { ...props };
this.setState( { open: false });
}

handleClick = () => {
this.setState({open: true});
};

handleClose = () => {
this.setState({open: false});
};

render() {
const actions = [
<FlatButton
label="取消"
primary={true}
onClick={this.handleClose}
/>,
<FlatButton
label="提交"
primary={true}
keyboardFocused={false}
onClick={this.handleClose}
/>,
];
return (
<div>
<IconButton
onClick={this.handleClick.bind(this)}
style={{ overflow: 'inherit' }}
tooltip="充值"
tooltipPosition="left"
>
<ActionAccountBalanceWallet color={cyan500} />
</IconButton>
<Dialog
title="请输入要转入的金额,转入后不可转出:"
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose} >

<TextField floatingLabelText="金额" />

</Dialog>
</div>
);
}
}

TopUpButton.propTypes = {
basePath: PropTypes.string,
record: PropTypes.object,
};

TopUpButton.defaultProps = {
style: { padding: 0 },
basePath: '',
record: {}
};

export default TopUpButton;

魔改思路

首先按照常规,将class的结构整理好,render函数要按照格式从别的地方复制过来。
这个地方难住我的就是如何将const类型中传入参数的过程保留。尝试了从render的函数的各种地方插入参数获取均已致败告终。最后去百度中搜索相关的资料发现,在React的Component类型中有一个constructor的方法,通过重写该方法来实现参数的载入。

此外,在列表中调用的类内部的函数,需要对其进行.bind(this)操作,否则会获取不到所属类的属性(如Record.id等)。在constructor函数中简单粗暴的将所有的属性通过“…”运算符展开到了所属类的state中。

同时借用了Dialog标签实现了不跳转页面实现一些功能。(魔改aor必备)

最后

暂时没发现什么其他的问题,欢迎交流。

更新

今天忽然发现有更机智的办法,对constructor的理解又深了一步。constructor会将传入的参数存入类的props属性中,直接在props中调用相关属性就可以了,没必要再次赋值到state中。此外,通过在render语句中添加:

1
const { data, data2 } = this.props;

就可以从props中直接取出属性来啦,避免了很多很多很多的麻烦。
这里提供了一个思路,回头试验一下

1
console.log(class);

看看能不能得到更令我惊喜的其他结果。

刚刚发现的参考链接

https://www.cnblogs.com/wonyun/p/5930333.html

Comments