zoukankan      html  css  js  c++  java
  • 记录一次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" />;
     }

    以上这些是在这次工作中的解决方案,方便记忆。

       

  • 相关阅读:
    网页版台球小游戏
    代码写响应式时钟效果
    如何使用SVN?
    TP框架---View视图层---模板继承(举例说明)
    ThinkPhp框架:文件上传
    ThinkPhp框架:验证码功能
    ThinkPhp框架:父类及表单验证
    ThinkPhp框架对“数据库”的基本操作
    对thinkphp的命名空间的理解
    控制器操作方法的调用
  • 原文地址:https://www.cnblogs.com/dump/p/10240610.html
Copyright © 2011-2022 走看看