React Wrapper สำหรับไลบรารีที่มีอยู่

Sep 05 2020

https://github.com/BingXiong1995/react-flv-player/blob/master/lib/wrapper/ReactFlvPlayer.js

import React, { Component } from 'react';
import flvjs from './flv.min';
import PropTypes from 'prop-types';


class ReactFlvPlayer extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
    this.flvPlayerRef = element => {
      this.flvPlayerRef = element;
    };
  }

  componentDidMount() {

    const {type , url, isLive, enableStashBuffer, stashInitialSize, hasAudio, hasVideo, handleError, enableWarning, enableError} = this.props;

    // 组件挂载后,拿到Ref进行操作
    if (flvjs.isSupported()) {
      const flvPlayer = flvjs.createPlayer({
        type,
        isLive,
        url,
        hasAudio,
        hasVideo
      },{
        enableStashBuffer,
        stashInitialSize
      });


      flvjs.LoggingControl.enableError = false;
      flvjs.LoggingControl.enableWarn = enableWarning;

      flvPlayer.attachMediaElement(this.myRef.current); // 将这个DOM付给第三方库
      flvPlayer.load();
      flvPlayer.play();
      flvPlayer.on('error', (err)=>{
        // console.log(err);
        handleError(err);
      });
    }
  }

  render() {
    const { height, width, isMuted,showControls } = this.props;
    return (
      <div>
        <video
          controls={showControls}
          muted={{isMuted}}
          ref={this.myRef}
          style={{height, width}}
        />
      </div>
    );
  }
}

ReactFlvPlayer.propTypes = {
  type: PropTypes.string,
  url: PropTypes.string.isRequired,
  isLive: PropTypes.bool,
  showControls: PropTypes.bool,
  hasAudio: PropTypes.bool,
  hasVideo: PropTypes.bool,
  enableStashBuffer: PropTypes.bool,
  stashInitialSize: PropTypes.number,
  height: PropTypes.string,
  width: PropTypes.string,
  isMuted: PropTypes.bool,
  enableWarning: PropTypes.bool,
  enableError: PropTypes.bool,
  handleError: PropTypes.func
};

ReactFlvPlayer.defaultProps = {
  type: 'flv',
  isLive: true,
  hasAudio: true,
  hasVideo: true,
  showControls: true,
  enableStashBuffer: true,
  stashInitialSize: 128,
  height: '100%',
  width: '100%',
  isMuted: false,
  handleError: (err)=>{console.log(err)},
  enableWarning: false,
  enableError: false
};

export default ReactFlvPlayer;

เขียน wrapper เมื่อนานมาแล้ว ฉันสงสัยว่าจะทำได้ดีกว่านี้ไหม ฉันสามารถปรับปรุงอะไรได้บ้างหรือมีปัญหากับโค้ด ขอบคุณ.

คำตอบ

3 CertainPerformance Sep 06 2020 at 05:42

flvPlayerRef?

ในตัวสร้างคุณมี

this.myRef = React.createRef();
this.flvPlayerRef = element => {
  this.flvPlayerRef = element;
};

นี่ค่อนข้างสับสน คุณสมบัติเป็นฟังก์ชันหรือองค์ประกอบขึ้นอยู่กับว่ามันถูกเรียกว่าเป็นฟังก์ชันก่อนหน้านี้หรือไม่และไม่ว่าด้วยวิธีใดก็ไม่ใช่การอ้างอิงดังนั้นจึงมีการตั้งชื่อผิดด้วย นอกจากนี้ยังไม่ได้ใช้ที่ใดในรหัสและผู้บริโภคของอินสแตนซ์แล้วจะได้รับการอ้างอิงถึง<video>องค์ประกอบผ่านmyRefคุณสมบัติ

ฉันต้องการลบflvPlayerRefสมบูรณ์และยังเปลี่ยนชื่อน้อยกว่าที่ข้อมูลmyRefชื่อคุณสมบัติการหรือvideoRefflvPlayerRef

เมื่อถึงจุดนั้นคุณสามารถทำให้สิ่งต่างๆกระชับได้โดยใช้ฟิลด์คลาสแทนตัวสร้าง:

class ReactFlvPlayer extends Component {
  videoRef = React.createRef();

  componentDidMount() {
    // ...

คุณยังสามารถพิจารณาใช้ส่วนประกอบที่ใช้งานได้แทนส่วนประกอบแบบคลาสตามที่ React แนะนำอย่างไม่เป็นทางการสำหรับโค้ดใหม่ แต่ไม่จำเป็นต้องใช้

อุปกรณ์ประกอบฉากที่ถูกทำลาย

บรรทัดนี้อ่านยาก:

const {type , url, isLive, enableStashBuffer, stashInitialSize, hasAudio, hasVideo, handleError, enableWarning, enableError} = this.props;

เมื่อมีคุณสมบัติมากกว่า 2 หรือ 3 รายการที่ต้องทำลายโครงสร้างฉันขอแนะนำให้วางแต่ละรายการไว้ในบรรทัดแยกกัน

const {
  type,
  url,
  isLive,
  // ...
} = this.props;

แต่ในกรณีนี้ส่วนสำคัญของคุณสมบัติที่มีการใช้เพียงที่จะผ่านเข้ามาในflvjs.createPlayerภายหลัง พิจารณาใช้ไวยากรณ์ที่เหลือเพื่อรวบรวมอ็อพชันเหล่านั้นไว้ในอ็อบเจ็กต์เดียวโดยไม่ต้องระบุทีละรายการ:

const {
  enableStashBuffer,
  stashInitialSize,
  handleError,
  enableWarning,
  enableError,
  ...createPlayerOptions
} = this.props;

enableErrorตัวแปรที่ไม่ได้ใช้ หากเป็นไปโดยเจตนาดีที่สุดคืออย่าดึงมันออกจากอุปกรณ์ประกอบฉากตั้งแต่แรก หรือบางทีคุณตั้งใจจะมอบหมายให้LoggingControl? เปลี่ยน

flvjs.LoggingControl.enableError = false;

ถึง

flvjs.LoggingControl.enableError = enableError;

การเยื้องที่ดีกว่าการสร้างบล็อกการเยื้องอื่นหลังจากตรวจสอบว่ารองรับ flvjs หรือไม่คุณสามารถพิจารณากลับก่อนเวลาได้หากไม่รองรับ:

componentDidMount() {
  if (!flvjs.isSupported()) {
    return;
  }
  const {
    enableStashBuffer,
    stashInitialSize,
    handleError,
    enableWarning,
    enableError,
    ...createPlayerOptions
  } = this.props;

  const flvPlayer = flvjs.createPlayer(
    createPlayerOptions,
    {
      enableStashBuffer,
      stashInitialSize
    }
  );
  // etc

การกลับมาก่อนเวลาค่อนข้างดีโดยเฉพาะอย่างยิ่งกับตรรกะที่ซับซ้อนมากขึ้นซึ่งอาจต้องใช้การเยื้องหลายระดับซึ่งอาจทำให้อ่านได้ยาก

ระยะห่างมีสถานที่บางที่ฉันคาดหวังที่จะเห็นพื้นที่ แต่ไม่เห็นใดก็ตามสไตล์รหัสในส่วนที่เหลือของสคริปต์ที่มีหรือที่ผมเห็นช่องว่างที่มีอาจจะไม่ควรใด ๆ เช่นconst {type , url,, },{, (err)=>{, const { height, width,(คุณต้องการพื้นที่นำหน้า / ต่อท้ายเมื่อทำลายโครงสร้างและด้วยวัตถุหรือไม่?)

ไม่ว่าคุณต้องการให้รูปแบบโค้ดของคุณเป็นแบบใดก็จะเป็นการดีที่จะต้องมีความสอดคล้องกัน - พิจารณาใช้ESLintเพื่อให้สไตล์ของคุณสอดคล้องกันแก้ไขสิ่งต่างๆโดยอัตโนมัติและเตือนคุณถึงจุดบกพร่องที่อาจเกิดขึ้นก่อนที่จะกลายเป็นข้อผิดพลาดรันไทม์