React: Where To Extend Object Prototype

后端 未结 2 462
抹茶落季
抹茶落季 2021-02-13 03:00

I created a pure React application using create-react-app. I would like to extend the String class and use it in one or more components. For example:



        
2条回答
  •  不思量自难忘°
    2021-02-13 03:26

    For TypeScript Language Users

    Tested on javascript based react-native project using expo-cli 36 and was wrote while working on Angular 7

    I had error that brought me here... I'm using js based react-native. previously i wrote a JS library, then due to some needs, i changed it to TS, and after switching to Angular, i had to create a firm library out of it to work in that environment...

    No i copied these file here, and i had error that i came to this thread, but all error gone once i compiled it for the first time, and it worked fully...

    Here's how i used it:

    i have utility class Utility.ts:

    export class Utility {
      /**
       * Returns False If Incoming Variable Is Not Null, void or Undefined, Otherwise True
       */
      public static isNullOrUndefined(obj: any|void): boolean {
        // return obj == null // juggling-check
        return typeof obj === 'undefined' || obj === null; // strict-check
      }
    
      /**
       * Returns False If Incoming Variable Does Not Contains Data, Otherwise True
       */
      public static isNullOrUndefinedOrEmpty(obj: any|void): boolean {
        if (Utility.isNullOrUndefined(obj)) {
            return true;
        }
    
        // typeof for primitive string, instanceof for objective string
        if (typeof(obj) === 'string' || obj instanceof String) {
          return (obj as string).valueOf() === '';
        } else if (obj instanceof Array) {
          return (obj as Array).length === 0;
        }
        throw new Error('Not Supported Exception');
      }
    ...
    }
    

    I have a definition class index.d.ts (I'm not sure but i think the file name was super important at Angular time, feel free to test...):

    declare global {
    
      interface StringConstructor { // for static methods
        format: (str: string, ...args: any[]) => string;
      }
    
      interface String { // for instance methods
        /**
         * Support StringComparision Options
         * https://stackoverflow.com/questions/10636871/ordinal-string-compare-in-javascript
         * @param searchString {!string}
         * @param position {?number}
         * @param comparision {?StringComparison}
         * @returns {number}
         */
        indexOfString: (searchString: string, position?: number, comparision?: StringComparison) => number;
        insertAt: (index: number, strText: string) => string;
        removeAt: (index: number, count: number) => string;
        replaceAt: (index: number, count: number, strReplacement: string) => string;
        overrideAt: (index: number, strText: string) => string;
    ...
    }
    

    And in the end i have my extension files Extensions.ts:

    import { Utility } from './Utility';
    
    /**
     * Support StringComparision Options
     * https://stackoverflow.com/questions/10636871/ordinal-string-compare-in-javascript
     */
    String.prototype.indexOfString = function(searchString: string, position?: number, comparision?: StringComparison): number {
      return Utility.indexOfString(this, searchString, position, comparision);
    };
    
    String.prototype.insertAt = function(index: number, strText: string): string {
      return this.substr(0, index) + strText + this.substr(index);
    };
    
    String.prototype.removeAt = function(index: number, count: number): string {
      if (Utility.isNullOrUndefined(count)) {
        count = this.length - index;
      }
      return this.substr(0, index) + this.substr(index + count);
    };
    

    Here i put all these files in a folder named util which doesn't matter at all, and i have direct access from Extensions to Utility and vise versa (or i didn't had any issue till now.

    NOW although i still can't use my extensions in react component, i can if i add a simple import: import '../util/Extensions';

    I tested it like this:

    import React from 'react';
    import { Text, View } from 'react-native';
    
    import '../util/Extensions'; //my import
    
    const SurveyScreen = props => {
        const z = 'sdwqew';
        const x = z.insertAt(2,'hassan'); //function from my custom extensions
        return (
            
                Hello World
                {x}
            
        );
    }
    
    export default SurveyScreen;
    

    Note at this time i do not have enough time to fully overview my old code, but here's the thing

    Second Note: if i import Extensions in Utility, it gives me warning Require cycles are allowed, but can result in uninitialized values. Consider refactoring to remove the need for a cycle. if i don't i see some error on VSCode, but it compiles fine, with no warning...

提交回复
热议问题