记录一次react相关总结
背景说明:元旦接到一个管理后台的项目,是一个关于自定义专题的项目。通过后台的配置自定义专题,前端根据专题模块进行渲染数据。由于管理后台是react做的前后分离,对于一个后端的我来说写写js也算是浅尝一下。如下记录一下工作中遇到的一些问题,和解决方案。
一、父组件调用子组件、以及子组件调用父组件
为什么会遇到这个问题,因为目前的需求是是无限增加Tabs标签,每一个Tabs标签页面又可以增加无限个子Tab标签,由于react只会子页面第一次加载的时候调用一次钩子函数,后期切换标签遍不在刷新页面,于是就会遇到父亲改变,需要改变子组件的数据,子组件改变也需要同步父组件的数据。
(1)父组件调用子组件解决方案如下:
let topicComList = [{ title: '轮播排序', content: <GroupSort topicId={that.state.topicId} componentId={this.state.componentId} onRef={this.onRef}/> , key: '1', closable: false }];
1)上面这段代码是父组件页面中书写的Tab的子组件内容,在子组件传递 onRef = { this.onRef }
//实现一个子组件对象
onRef = (ref) => {
this.child = ref;
}
2)在父组件中实现这个箭头函数,并且在页面上定义一个child state
这个的作用是将子组件的对象传递给父组件的child,后期便通过this.child.fun()去调用子组件的方法
3)子组件这样写
componentDidMount() {
this.props.onRef(this)
this.state.topicId = this.props.topicId;
this.topicComponentGroupList();
}
只看第二行,接收父组件传递的 onRef 指定一个this即可
4)实现如上操作就可以进行调用子组件的方法了,实现如下
if ( typeof this.child == 'object' ) {
this.child.onRefFun();
}
这样就可以正常访问子组件的onRefFun方法了,其实很方便。
(2)子组件调用父组件解决方案如下:
let topicComList = [{ title: '轮播排序', content: <GroupSort topicId={that.state.topicId} componentId={this.state.componentId} clickCallBack={that.clickCallBack} /> , key: '1', closable: false }];
同样是这样的一个子组件,给子组件传递一个函数 clickCallBack, 子组件便可通过 this.props.clickCallBack()去调用父亲的函数。
1)首先在父组件实现这个函数 clickCallBack
//子组件调用父组件函数
clickCallBack = () => {
this.topicComponentGroupList();
}
2)在子组件中,在需要更新父组件的地方,this.props.clickCallBack即可
handleSubmit = (e) => {
e.preventDefault();
let that = this;
that.setState({ loadingForm: true });
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
let saveVal = {};
saveVal = {
anchors:[{
name: values.groupName,
id: values.anchor
}]
}; that.props.dispatch({
type: 'editgroup/edit',
payload: {
topicId: that.state.topicId,
componentId : this.state.componentId,
componentGroupId: that.state.groupId,
value: JSON.stringify(saveVal),
groupName: values.groupName
}
}).then(function (response) {
Modal.success({
title: '消息',
content: '操作成功!' ,
});
that.setState({
loadingForm: false,
messageType:'success',
message:'温馨提示:恭喜小主,您已保存成功!'
});
that.props.clickCallBack();
}.bind(that)).catch( function ( errmsg ) {
Modal.error({
title: '消息',
content: '错误信息: ' + errmsg,
});
that.setState({ loadingForm: false });
});
} else {
that.setState({ loadingForm: false });
}
});
}
以上就是关于组件直接的互相调用。
二、如果实现js的异步执行 Promise
根据需求上传图片需要获取图片的宽和高,但是由于js都是异步执行的,往往我这边的宽和高还没有或取到,js的操作流程就已经结束了,导致不能够100%获取到图片的宽和高,通过查询知道 Promise 是专门执行异步操作的 ,它会等待异步完成执行完成在继续执行下去。
写法如下:
beforeUpload = file => {
const { fileSizeLimit = 5 } = this.props;
const isJPG = imageTypes.includes(file.type);
if (!isJPG) {
Modal.error({
title: '只支持上传图片类型!'
});return false;
}
const isLt2M = file.size / 1024 / 1024 < fileSizeLimit;
if (!isLt2M) {
Modal.error({
title: `文件大小不能超过${fileSizeLimit}M!`
});return false;
}
return isJPG && isLt2M && this.checkImageWH(file);
}; checkImageWH = (file) => {
let self = this;
return new Promise(function (resolve, reject) {
let filereader = new FileReader();
filereader.onload = e => {
let src = e.target.result;
const image = new Image();
image.onload = function () {
self.state.imageWidth = this.width;
self.state.imageHeight = this.height;
if (!self.state.imageWidth) {
Modal.error({
title: '请上传图片的宽'
})
reject();
} else if (!self.state.imageHeight) {
Modal.error({
title: '请上传图片的高',
})
reject();
} else {
resolve();
}
};
image.onerror = reject;
image.src = src;
};
filereader.readAsDataURL(file);
});
}
以上的关键点就在于这一句: return isJPG && isLt2M && this.checkImageWH(file); 同步执行成功才成功,否则就失败。
由此可见 Promise 最后只会返回成功,或者失败。
具体可借鉴https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000
三、编辑时图片信息不显示出来
原因说明,由于react 渲染页面render会多次,而图片组件只会识别第一次的render渲染,从而导致当datasource有数据时图片信息不显示,而其他数据显示没有问题。
解决方案:这个方法主要是占一个坑,不让页面走下去,直到有数据时才真正的渲染html
if (this.state.topicId && this.state.dataSource.length === 0) {
return <Spin size="large" />;
}
以上这些是在这次工作中的解决方案,方便记忆。
记录一次react相关总结的更多相关文章
- React相关知识和经验的碎片化记录
React相关知识和经验的碎片化记录 1.Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a chil ...
- 示例开发过程记录:meteor,react,apollo
本示例记录一个开发过程: 1)参考 Meteor React TUTORIAL教程 https://www.meteor.com/tutorials/react/creating-an-app 2). ...
- 常用的package.json以及React相关
常用的package.json以及React相关 前言 package.json 的简单介绍 简单版的 package.json 必备属性(name & version) name 字段 ve ...
- 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux
因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...
- 记录工作中linux相关操作
在项目部署之后,查看日志能查看部署结果是否正确部署. 最开始查看日志我会使用cat service.log tail -f service.log vim service.log 打开日志之后 /+查 ...
- ES6深入学习记录(一)class方法相关
今天学习class相关的一些使用方法,着重在于class extends class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多. 上面的代码定义了一 ...
- react相关知识点
1.react内联样式写法: <div style={{width:'200px',height:'100px',border:'1px solid red'}}> </div> ...
- 使用hibernate更新数据库记录的信息的相关学习记录
截选代码(可能遗漏标点符号): package name.sql; import java.util.List; import name.session.HibernateSessionFactory ...
- react相关
react 简单入门 ant 蚂蚁金服react组件 redux 阮一峰入门react material-ui组件库 webpack入门 http://www.jianshu.com/p/42e115 ...
随机推荐
- mysql操作命令梳理(5)-执行sql语句查询即mysql状态说明
在日常mysql运维中,经常要查询当前mysql下正在执行的sql语句及其他在跑的mysql相关线程,这就用到mysql processlist这个命令了.mysql> show process ...
- ELK实时日志分析平台环境部署--完整记录
在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...
- sql-server安装
ubuntu安装sql-server https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-ubuntu?view ...
- 12.25daily_scrum
今天是圣诞节,大家在度过了一个愉快的节日同时,同时也收到了最好的圣诞礼物,就是调试工作已经进入尾声,接下来我们组的主要任务就是M2阶段的总结了.为了更好的做好M2阶段的收官工作,我们组决定分配相当的一 ...
- 《Linux内核设计与实现》第17章学习笔记
第17章.设备与模块 17.1设备类型 1.块设备(blkdev): 寻址以块为单位,通常支持重定位操作.通过称为“块设备节点”的特殊文件来访问. 2.字符设备(cdev): 不可寻址,仅提供数据的流 ...
- 【MOOC EXP】Linux内核分析实验六报告
程涵 原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述和进程的创建 知识点梳理: ...
- Oracle系列(一): Oracle数据恢复
Oracle数据恢复 在使用Oracle的时候,突然一部小心update或者delete全部数据后怎么办? select * from table as of timestamp to_timest ...
- 软件工程(GZSD2015)学生博客列表
2015年贵州师范大学软件工程课程学生博客列表 陈小丽 郑倩 唐洁 周娟 李利思 肖俊 罗文豪 周静 徐明艳 毛涛 邓洪虹 岳庆 李盼 安坤 何亚 涂江凤 张义平 杨明颢 杨家堂 胡贵玲 寿克霞 吴明 ...
- Linux预处理、编译、汇编、链接和运行的过程(包括一些基本的命令)
转自Quinn0918的博客 一.预编译 1.将所有的#define删除,并展开所有的宏定义: 2.处理所有的预编译指令,例如:#if,#elif,#else,#endif; 3.处理#include ...
- Qt__状态栏(statusBar)
转自豆子空间 状态栏位于主窗口的最下方,提供一个显示工具提示等信息的地方.一般地,当窗口不是最大化的时候,状态栏的右下角会有一个可以调节大小的控制点:当窗口最大化的时候,这个控制点会自动消失.Qt提供 ...