背景说明:元旦接到一个管理后台的项目,是一个关于自定义专题的项目。通过后台的配置自定义专题,前端根据专题模块进行渲染数据。由于管理后台是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相关总结的更多相关文章

  1. React相关知识和经验的碎片化记录

    React相关知识和经验的碎片化记录 1.Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a chil ...

  2. 示例开发过程记录:meteor,react,apollo

    本示例记录一个开发过程: 1)参考 Meteor React TUTORIAL教程 https://www.meteor.com/tutorials/react/creating-an-app 2). ...

  3. 常用的package.json以及React相关

    常用的package.json以及React相关 前言 package.json 的简单介绍 简单版的 package.json 必备属性(name & version) name 字段 ve ...

  4. 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux

    因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...

  5. 记录工作中linux相关操作

    在项目部署之后,查看日志能查看部署结果是否正确部署. 最开始查看日志我会使用cat service.log tail -f service.log vim service.log 打开日志之后 /+查 ...

  6. ES6深入学习记录(一)class方法相关

    今天学习class相关的一些使用方法,着重在于class extends class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多. 上面的代码定义了一 ...

  7. react相关知识点

    1.react内联样式写法: <div style={{width:'200px',height:'100px',border:'1px solid red'}}> </div> ...

  8. 使用hibernate更新数据库记录的信息的相关学习记录

    截选代码(可能遗漏标点符号): package name.sql; import java.util.List; import name.session.HibernateSessionFactory ...

  9. react相关

    react 简单入门 ant 蚂蚁金服react组件 redux 阮一峰入门react material-ui组件库 webpack入门 http://www.jianshu.com/p/42e115 ...

随机推荐

  1. mysql操作命令梳理(5)-执行sql语句查询即mysql状态说明

    在日常mysql运维中,经常要查询当前mysql下正在执行的sql语句及其他在跑的mysql相关线程,这就用到mysql processlist这个命令了.mysql> show process ...

  2. ELK实时日志分析平台环境部署--完整记录

    在日常运维工作中,对于系统和业务日志的处理尤为重要.今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为例说明,如有误述,敬请指出)~ ==== ...

  3. sql-server安装

    ubuntu安装sql-server https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-ubuntu?view ...

  4. 12.25daily_scrum

    今天是圣诞节,大家在度过了一个愉快的节日同时,同时也收到了最好的圣诞礼物,就是调试工作已经进入尾声,接下来我们组的主要任务就是M2阶段的总结了.为了更好的做好M2阶段的收官工作,我们组决定分配相当的一 ...

  5. 《Linux内核设计与实现》第17章学习笔记

    第17章.设备与模块 17.1设备类型 1.块设备(blkdev): 寻址以块为单位,通常支持重定位操作.通过称为“块设备节点”的特殊文件来访问. 2.字符设备(cdev): 不可寻址,仅提供数据的流 ...

  6. 【MOOC EXP】Linux内核分析实验六报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述和进程的创建 知识点梳理: ...

  7. Oracle系列(一): Oracle数据恢复

     Oracle数据恢复 在使用Oracle的时候,突然一部小心update或者delete全部数据后怎么办? select * from table as of timestamp to_timest ...

  8. 软件工程(GZSD2015)学生博客列表

    2015年贵州师范大学软件工程课程学生博客列表 陈小丽 郑倩 唐洁 周娟 李利思 肖俊 罗文豪 周静 徐明艳 毛涛 邓洪虹 岳庆 李盼 安坤 何亚 涂江凤 张义平 杨明颢 杨家堂 胡贵玲 寿克霞 吴明 ...

  9. Linux预处理、编译、汇编、链接和运行的过程(包括一些基本的命令)

    转自Quinn0918的博客 一.预编译 1.将所有的#define删除,并展开所有的宏定义: 2.处理所有的预编译指令,例如:#if,#elif,#else,#endif; 3.处理#include ...

  10. Qt__状态栏(statusBar)

    转自豆子空间 状态栏位于主窗口的最下方,提供一个显示工具提示等信息的地方.一般地,当窗口不是最大化的时候,状态栏的右下角会有一个可以调节大小的控制点:当窗口最大化的时候,这个控制点会自动消失.Qt提供 ...