skip to Main Content

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 

2

Answers


  1. There are no functional differences besides readability and very slight performance hit by the creation of temporary objects / iterating the enumerable properties (performance difference surely would be negligible to the point where it’d be hard to even measure accurately).

    const PageSection({children}) => <div>{children}</div>;
    const Header({children}) => <div>{children}</div>;
    const Body({children}) => <div>{children}</div>;
    
    PageSection.Header = Header;
    PageSection.Body = Body;
    
    export default PageSection;
    

    Is equivalent to

    const PageSection({children}) => <div>{children}</div>;
    const Header({children}) => <div>{children}</div>;
    const Body({children}) => <div>{children}</div>;
    
    // This performs a function call once `Object.assign()`,
    // and you need to create a temp object `{Header, Body}`
    // to enumerate and assign to `PageSection`, hence why
    // it is technically "less performant."
    export default Object.assign(PageSection, {
      Header,
      Body,
    });
    

    I prefer the first example, because it is much clearer what the intent is.

    Login or Signup to reply.
  2. (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 blocks 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};
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search