You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
import React from 'react';
 | 
						|
 | 
						|
interface Props {
 | 
						|
  /** The View class, which will be instantiated then treated like a Backbone View */
 | 
						|
  readonly View: BackboneViewConstructor;
 | 
						|
  /** Options to be passed along to the view when constructed */
 | 
						|
  readonly options: object;
 | 
						|
}
 | 
						|
 | 
						|
interface BackboneView {
 | 
						|
  remove: () => void;
 | 
						|
  render: () => void;
 | 
						|
  el: HTMLElement;
 | 
						|
}
 | 
						|
 | 
						|
interface BackboneViewConstructor {
 | 
						|
  new (options: object): BackboneView;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Allows Backbone Views to be rendered inside of React (primarily for the Style Guide)
 | 
						|
 * while we slowly replace the internals of a given Backbone view with React.
 | 
						|
 */
 | 
						|
export class BackboneWrapper extends React.Component<Props, {}> {
 | 
						|
  protected el: HTMLElement | null = null;
 | 
						|
  protected view: BackboneView | null = null;
 | 
						|
 | 
						|
  public componentWillUnmount() {
 | 
						|
    this.teardown();
 | 
						|
  }
 | 
						|
 | 
						|
  public shouldComponentUpdate() {
 | 
						|
    // we're handling all updates manually
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  public render() {
 | 
						|
    return <div ref={this.setEl} />;
 | 
						|
  }
 | 
						|
 | 
						|
  protected setEl = (element: HTMLDivElement | null) => {
 | 
						|
    this.el = element;
 | 
						|
    this.setup();
 | 
						|
  };
 | 
						|
 | 
						|
  protected setup = () => {
 | 
						|
    const { el } = this;
 | 
						|
    const { View, options } = this.props;
 | 
						|
 | 
						|
    if (!el) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    this.view = new View(options);
 | 
						|
    this.view.render();
 | 
						|
 | 
						|
    // It's important to let the view create its own root DOM element. This ensures that
 | 
						|
    //   its tagName property actually takes effect.
 | 
						|
    el.appendChild(this.view.el);
 | 
						|
  };
 | 
						|
 | 
						|
  protected teardown() {
 | 
						|
    if (!this.view) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    this.view.remove();
 | 
						|
    this.view = null;
 | 
						|
  }
 | 
						|
}
 |