Home > Blockchain >  how to correctly refactor props/condition for easier reading React/Js
how to correctly refactor props/condition for easier reading React/Js

Time:02-24

I would like to explain my problem of the day.

I have an element, and inside I have 2 conditions on props

when i reuse the component i call the props socialSupervisor or socialOperator.

it works perfectly.

on the other hand I find it long to read, so I am looking for a way of refactoring to have 0 props or 1 only.
I am open to any proposal thank you very much.

<p>
  {socialSupervisor &&
                        (!isLoading &&
                        lastMessage?.type === "text" &&
                        lastMessage?.author?.type === "supervisor" &&
                        lastMessage?.author?._id === authUser._id ? (
                            <span>
                                Moi:
                            </span>
                        ) : lastMessage?.author?.type === "operator" ? (
                            <span>
                                conseiller: {lastMessage?.author?.name}:
                            </span>
                        ) : lastMessage?.author?.type === "supervisor" ? (
                            <span>
                                superviseur: {lastMessage?.author?.name}:
                            </span>
                        ) : (
                            ""
                        ))}
                    {socialOperator &&
                        (!isLoading &&
                        lastMessage?.type === "text" &&
                        lastMessage?.author?.type === "operator" ? (
                            <span>
                                Moi:
                            </span>
                        ) : lastMessage?.author?.type === "supervisor" ? (
                            <span>
                                superviseur: {lastMessage?.author?.name}:
                            </span>
                        ) : (
                            ""
                        ))}
</p>

CodePudding user response:

An improvement may be:

function getLabel(type) {
    switch (type) {
        case "operator":
            return "conseiller";
        case "supervisor":
            return "superviseur";
        case "me":
            return 'Moi';
    }
}

function renderSocialSupervisor() {
    const isMe = lastMessage?.author?._id === authUser._id;
    const label = getLabel(isMe ? 'me' : lastMessage?.author?.type);
    return isLoading || lastMessage?.type !== "text" ? null : (
        <span>{label}: {lastMessage?.author?.name}</span>
    );
}

function renderSocialOperator() {
    const isMe = lastMessage?.author?._id === authUser._id;
    const label = getLabel(
        lastMessage?.author?.type === "operator"
            ? "me"
            : lastMessage?.author?.type
    );
    return isLoading || lastMessage?.type !== "text" ? null : (
        <span>
            {label}: {lastMessage?.author?.name}
        </span>
    );
}

return (
    <p>
        {socialSupervisor && renderSocialSupervisor()}
        {socialOperator && renderSocialOperator()}
    </p>
);

Better would be to write separate components, and to pass the right props to them. The less logic you put inside a single component return statement the better.

CodePudding user response:

De-structure nested props/variables:

lastMessage to {author, type}

Or even refactor names of author and instead of _id and type to author_id and author_type, so you can de-structure easily:

{{author_id, author_type}, type}

CodePudding user response:

I'll start by asking you what the types of socialSupervisor and socialOperator props? I can guess they're booleans (true or false), so if one of them is true, does it mean the other prop will be false? If the answer is yes, you can use the ternary operator to render the component with one prop (you can decide which one to leave).

{ socialSupervisor ? 
    <span>Social supervisor render</span> :
    <span>Social operator render</span> }

Secondly, I found that you re-use your spans, they share the same classes and only vary on their content. If you ask me, I would create a function that returns the name of the author. Then, I would create a function that returns a span with the content I need.

const getAuthorLabel = (type, name) => {
    switch (type) {
        'me': return 'Moi: ';
        'supervisor': return `superviseur: ${name}`;
        'operator': return `conseiller: ${name}`;
        default: return '';
    }
}

const getAuthLabel = ({ author, type }) => {
    const isMe = author?._id === authUser?._id;
    const labelType = isMe && type === 'text' ? 'me' : author?.type;
    const label = getAuthorLabel(labelType, author?.name);
    return <span className="text-xs font-semibold mr-1">{label}</span>;
}

And last but not least, do you need these props? I mean, the last message would still be the last message, with all of its props, including the message type, author type, author name, author id, etc. So maybe you could render the label directly in the paragraph element, without the need to check for their values. Of course, this is irrelevant if you need these props for something else, or they mean something else by themselves.

A whole refactor for the component, as I can imagine it would be something similar to this:

const YourComponent = ({ lastMessage }) => {
    // your other logic goes here    
    
    return <p>{renderAuthLabel(lastMessage)}</p>;
}
  • Related