Search code examples
javascriptreactjsobject-literal

How to call function using a dynamic function name ReactJS?


I have created a component to show field names. Basically, I am working on UI Builder type UI, where every single element has multiple settings and contains all the elements like text field, number field, switch, checkbox, radio, select list and dropdown etc. This list increases day by day according to the settings needed. I have created a separate component for elements where I'm building elements on the basis of a key.

Now, the problem is I'm building a "switch case" to render the elements. I have already created 40 cases right now and chances are that it will grow further, which leads to bad code format.

import { Fragment } from React;

function Elements() {
    function formFields(fieldData, data, info, options) {
        let fields;
        /** Main return function */
        switch (fieldData?.type) {
            case "number":
                return (
                    <InputField
                        // inputfield code here
                    />
                )
            case "switch":
                return (
                    <Switch
                        // switch code here
                    />
                )
            case "dropdown":
                return (
                    <Dropdown
                        // ........
                    />
                )
            case "shadowOffset":
                return (
                    <div className="mb-15">
                        //.......
                    </div>
                )
            . 
            . 
            . 
            // ...... multiple cases
            default:
                return null;
        }
    }

    return(
        <Fragment>
            {formFields(fieldData, data, info, options)}
        </Fragment>
    )
}

Requirement::

Instead of maintaining a switch case I want to split the cases into functions and want to call function names dynamically using dynamic variable data(This means I will create function names with the keys I have used inside the switch case and now want to call these functions using the dynamic name.).

What I have already tried before

  • I have used the "eval" js function but it is not recommended and not a good option in terms of security purposes. Is there any other function which can work as "eval" in ReactJS?
  • I have also tried to achieve this using the "Object literal" concept. I have converted the switch cases in the object and its keys and then call the function with the key. But the problem is I am not able to pass data as an argument inside the function called inside object literal. I have called like this inside JSX::

myObjectLiteral[dynamicKey](arg1, arg2)

I'm getting an error when adding () after the object literal call:

Elements.js:715 Uncaught TypeError: fields[(0 , Services_BuilderServices__WEBPACK_IMPORTED_MODULE_5__.getFieldType)(...)] is not a function

Basically, I am not able to call function literal string using dynamic variables.

Please help to suggest how I can call the function name using a dynamic variable in ReactJS.


Solution

  • I believe in jsx or tsx the best way to achieve this is to use map object. in vue there is a <component /> component that will solve your problem very compact but react is not

    import { Fragment } from React;
    
    const mapComponent = {
      number(props) {
        return <InputField {...props}
                            // inputfield code here
                        />
      },
      ...
      dropdown(props) {
        return <Dropdown {...props}
                            // ........
                        />
      },
      ...
    }
    
    function Elements() {
        function formFields(fieldData, data, info, options) {
            /** Main return function */
            return mapComponent[fieldData?.type]?.(options) ?? null
        }
    
        return(
            <Fragment>
                {formFields(fieldData, data, info, options)}
            </Fragment>
        )
    }