【问题标题】:Typescript and React refs without using inline lambdas不使用内联 lambda 的 Typescript 和 React refs
【发布时间】:2016-12-15 01:40:03
【问题描述】:

以下 TypeScript 中的快速示例展示了一种无需使用内联(这被认为对性能不利)来获取类型化 ref 的方法。然而,必须定义两个变量(refAnimationWrapperrefAnimationWrapperHandler)来定义一个引用是相当难看的。有没有人有更简单的解决方案,@decorators 可能是一个解决方案吗?

https://www.typescriptlang.org/docs/handbook/decorators.html

import * as React from 'react';
import {TweenMax} from 'gsap';

export class TransitionDummy extends React.Component<any, any> {
    private transitionDuration = 0.4;

    private refAnimationWrapper:HTMLDivElement;
    private refAnimationWrapperHandler = (ref:HTMLDivElement) => this.refAnimationWrapper = ref;

    constructor(props) {
        super(props);
    }

    public componentWillEnter(done) {
        TweenMax.fromTo(this.refAnimationWrapper, this.transitionDuration, {opacity: 0}, {opacity: 1, onComplete: done});
    }

    public componentWillLeave(done) {
        TweenMax.to(this.refAnimationWrapper, this.transitionDuration, {opacity: 0, onComplete: done});
    }
    
    public render() {
        return (
            <div ref={this.refAnimationWrapperHandler}>
                {this.props.children}
            </div>
        );
    }
}

【问题讨论】:

  • 为什么&lt;div ref={(input) =&gt; this.refAnimationWrapper = input}&gt; 的性能比&lt;div ref={this.refAnimationWrapperHandler}&gt; 差?
  • 哦,没关系,我看到人们在谈论它here。就个人而言,我不会为了节省几微秒而牺牲代码质量。
  • 我只使用内联 lambdas medium.com/@basarat/…
  • @DavidSherret 我可能最终会采用这种方法,我只是想知道是否有办法同时获得这两种方法。但可能对性能的影响很小。
  • @basarat 是的,那是我试图避免的。

标签: reactjs typescript


【解决方案1】:

您可以将它们都包装在一个类中,这样每个 ref 都有一个成员:

class RefedElement<T> {
    wrapper: T;
    handler = (ref: T) => this.wrapper = ref;
}

export class TransitionDummy extends React.Component<any, any> {
    private transitionDuration = 0.4;

    private refAnimation: RefedElement<HTMLDivElement>;

    constructor(props) {
        super(props);
        this.refAnimation = new RefedElement<HTMLDivElement>();
    }

    public componentWillEnter(done) {
        TweenMax.fromTo(this.refAnimation.wrapper, this.transitionDuration, {opacity: 0}, {opacity: 1, onComplete: done});
    }

    public componentWillLeave(done) {
        TweenMax.to(this.refAnimation.wrapper, this.transitionDuration, {opacity: 0, onComplete: done});
    }

    public render() {
        return (
            <div ref={ this.refAnimation.handler }>
                {this.props.children}
            </div>
        );
    }
}

【讨论】:

  • 这段代码是否为你编译,我得到:Error:(21, 9) TS2322:Type 'RefedElement&lt;{}&gt;' is not assignable to type 'RefedElement&lt;HTMLDivElement&gt;'. Type '{}' is not assignable to type 'HTMLDivElement'. Property 'align' is missing in type '{}'.
  • 我也不认为这段代码可以节省很多打字,除非我们可以将新的 RefedElement() 调用直接移动到变量定义中。
  • 对,应该是new RefedElement&lt;HTMLDivElement&gt;(),在答案中固定。一旦你有多个“RefedElement”,它确实可以节省代码量。
猜你喜欢
  • 2020-01-14
  • 2021-01-22
  • 1970-01-01
  • 2022-12-05
  • 2018-05-27
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多