Search code examples
javascriptreactjstypescriptreact-nativetsx

Object.assign vs. assignment operator (i.e. = ) for React components


Simple question: I have read a couple of answers such as this on the differences between Object.assign and the assignment operator (i.e. =) and understand all the points brought up such as that the first copies the object while the latter simply assigns the address.

I want to make a decision on which one to use and would like to know what the implications are for React components as I have seen it being done both ways. Is one an antipattern, in the context of React components, which I should not be considering?

An example of my use-case is as shown below:

function PageSection({children}) {
    return <div>{children}</div>
}

function Header({children}) {
    return <div>{children}</div>
}

function Body({children}) {
    return <div>{children}</div>
}

// Attach components to the `PageSection` component.
export default Object.assign(PageSection, {
    Header,
    Body,
});

And a related question is, is it an acceptable practice to assign to a property of a property i.e.

Header.CloseButton = CloseButton
PageSection.Header = Header 

Solution

  • (Non-)Idiomatic use of technology

    In programming, one concept that is important to development is the idiomatic use of technology. This means that you should use the programming language or library or building block for what it is intended to be used for, and use it the way it was intended to be used. Aside from avoiding potential issues, using technology idiomatically makes it easier for others to understand your intent, which in turns makes your code easier to maintain.

    Assigning to a React Function Component

    A React Component is intended to render HTML. Adding properties to a Function Component is absolutely an anti-pattern because it's not meant to be a generic container and just because you can add properties to any Javascript type doesn't mean you should.

    You haven't explained what you are trying to do. If you're looking for a way to group these 3 related components together, you could put them in a plain object:

    const BlogComponents = {
        pageSection: PageSection,
        header: Header,
        body: Body,
    };
    

    Assignment Operator (=) vs Object.assign()

    As explained above, I don't think we should be adding properties to a React Function Component. But to address the part of your question comparing the two ways of doing things, I can say that

    Object.assign() is often used to provide default values. That is, you know that you have e.g. 5 different command-line options. Each one has a default value, and you don't know which ones were specified without inspecting the object containing the command-line options that were captured.

    You could do:

    const options = {};
    options.isHelp = arguments.isHelp ?? defaultIsHelp;
    options.beVerbose = arguments.beVerbose ?? defaultBeVerbose;
    

    or:

    const options = Object.assign({}, defaults, arguments);
    

    The latter is much more readable, in my opinion.

    Generally, use the assignment operator if you have finite known fields and no defaults.

    car.doorColor = 'yellow';
    car.hasRollbar = false;
    

    It might sometimes be convenient to use Object.assign() if there are many fields to copy.

    Spread Syntax -- the new Object.assign()

    Spread Syntax is similar to Object.assign()

    Rewriting the example above:

    const options = {...defaults, ...arguments};