DEV Community

joon
joon

Posted on

Useful tips and tricks React/js - part1

Hi all. This is my first post. I wont bore you with introducing myself. I'll leave that at the end if you're interested.

Let the tips begin 😄

0. [React] use hooks if you're not using them already

Just added this because I realized you might not be. Personally I'll refactor a project of 2mb to hooks if I it was written using class components. But then again, who am I to judge? Skip this post until you embrace the power of hooks.

1. [React] useState like useReducer - selectively

I actually saw this one scrolling through react posts in this community, except the post used it like it was nothing - while I felt like I struck a gold-mine and applied it to my everyday coding habits immediately.
A bit of background info - useReducer is (in my humble opinion) pretty much a wrapper for useState to make sure you don't end up setting multiple states and inducing multiple rerenders at the same time like the following

//  imports etc...
//  ...
const aFunction = (var1, var2, someCondition) => {
    if(someCondition === "something") {
        setAState(var1)
        setBState(var2)
    } else {
        setAState(var1)
    }
    //  you get the point
}
Enter fullscreen mode Exit fullscreen mode
I love the smell of pointless multiple rerenders

useReducer nicely wraps up the above code to make sure both can be done in a single rerender.
But we have to define action types, and a reducer and all that stuff we're sick of doing in redux, for every case of useState. And it starts to feel a bit bloaty and botherish when you want to reduce a single rerender. So here's the gist.

//  imports
//  ...
const [reducerAlt, setReducerAlt] = useState({});

const handleState = vals => {
    if(vals.isReducer === true && _.isObject(vals.action)) {
        if(vals.action.type === undefined) throw new Error("action type is not defined")
        const valsCopy = {...vals, isReducer: undefined, action: undefined};
        switch(vals.action.type) {
            // do reducer things with valsCopy we're not bothered to and use it to set state.
        }
        return;
    }
    setReducerAlt(prev => ({...prev, ...vals}));
}

//  nice and simple
const aFunction = (var1, var2, someCondition) => {
    if(someCondition === "something") {
        handleState({aState: var1, bState: var2});
    } else {
        handleState({aState: var1});
    }
}

Enter fullscreen mode Exit fullscreen mode

Not sure how well I wrote that code because I wrote it straight from markdown, but you'll probably get the gist of it. Use it like a reducer when needed, simply overwrite the state with values if not bothered.
Yes this method is error-prone but I'm sure we can all add our error-handling by ourselves without any problems... right?...

2. [React, but also JS probably] Ternary operators are tempting but not really readable. Switch cases take too many lines. So?...

I'll just throw this here. My jaw dropped as well when I found this was possible. So many places I have to fix now.

const aSwitchCase = gotItFromSomewhere();

return (
    <>
        {
            {
                case1: <Component1 />
                case2: <Component2 />
                case3: <Component3 />
                case4: SomeFunctionThatReturnsAComponent()
                case5: "yeah anything it's an object and the 'aSwitchCase' is referencing the property"
                "undefined": () => throw Error("Havent' really tried this one but I think it'll work maybe? Please comment if it doesn't I'll delete this.")
                "null": () => throw Error("ditto above")
            }[`${aSwitchCase}`]
        }
    </>
)
Enter fullscreen mode Exit fullscreen mode

Just a quick note that I believe ternary operators are awesome as well and work fine as long as you're using it with a boolean. But the above example is in my opinion infinitely better if you find yourself doing something like this

const something = fromSomething();
return (
    <>
        {something === "a" ? <a /> : something === "b" ? <b /> : something === "c" ? <c /> : undefined : undefined : undefined}
    </>
)
//  yeah it's usually longer and much more unreadable. But this alone is difficult to read which proves my point.
Enter fullscreen mode Exit fullscreen mode

or this

const something = fromSomething()
switch something {
    case "a":
        return <a />;
    case "b":
        return <b />;
    case "c":
        return <c />;
    default:
        throw new Error("well not infinitely better I agree");
}
Enter fullscreen mode Exit fullscreen mode

When it comes to code-readability the final snippet might be more 'readable'
but for someone like me who loves forcing as much logic as possible in a single line as long as it's 'readable' - this method was a god-send.

[React] 3. I'm not affiliated to the guy in the video or the company or absolutely anything but....

If you're interested in optimizing React and have no difficulty understanding British English,
watch THIS.
I scrolled through and read several posts for about 2 weeks on optimizing react on devto, but this video was pretty much better at everything and more informative at the same time. Personally I'd choose watching the video again over a comedy skit - it was that funny(to me)

[JS] 4. Why you should use modules like lodash

I'm a big fan of lodash. But I didn't use to be. Until this happened.

const somethingAmazing = (var) => {
    if(typeof var !== 'object') throw new Error("not an object");
    // do stuff
    return "did stuff"
}

somethingAmazing(null); // not a bloody error
Enter fullscreen mode Exit fullscreen mode

Turns out 'null' is an object. (Obviously why js is so popular)
Might look like a simple error, but if that is nested inside multiple components, whisks through redux and you only get weird errors that seem totally unrelated because your whole logic counts on 'var' being NOT null - this could take hours to debug if JS and the universe is trying to screw you over(as always).
Just use libraries like lodash if you care for your sanity.

const somethingAmazing = (var) => {
    if(!_.isObject(var)) throw new Error("not an object");
    // do stuff
    return "did stuff"
}

somethingAmazing(null); // yes error
Enter fullscreen mode Exit fullscreen mode

Wrapping up

I was planning on writing at least 5 tips that I picked up, but I'm too tired(it's half past 2am). Maybe I'll return with a part 2. Who knows. Hope you got some useful stuff from this post. Cheers - keep coding.

PS Any feedback is greatly appreciated and will 'possibly' motivate me for a part 2.

Top comments (4)

Collapse
 
josemunoz profile image
José Muñoz

I have a different approach to the object switch cases. Instead of:

const aSwitchCase = gotItFromSomewhere();

return (
    <>
        {
            {
                case1: <Component1 />
                case2: <Component2 />
                case3: <Component3 />
                case4: SomeFunctionThatReturnsAComponent()
                case5: "yeah anything it's an object and the 'aSwitchCase' is referencing the property"
                "undefined": () => throw Error("Havent' really tried this one but I think it'll work maybe? Please comment if it doesn't I'll delete this.")
                "null": () => throw Error("ditto above")
            }[`${aSwitchCase}`]
        }
    </>
)

I wrap the components into a function and use optional chaining to extract the content, you could call it a monad if you like:

const aSwitchCase = gotItFromSomewhere()
const content =  {
                case1: () => <Component1 />,
                case2: () => <Component2 />,
                case3: () => <Component3 />,
                case4: SomeFunctionThatReturnsAComponent,
            }[aSwitchCase]

return content?.()
Collapse
 
fly profile image
joon • Edited

Thank you for the feedback.

I totally agree and now I don't think I'll ever use switch cases anymore. :)

Collapse
 
idiglove profile image
Faith Morante

I loved the switch case in return function! Useful <3

Collapse
 
fly profile image
joon

Thanks for the feedback!

That was actually the tip that gave me the courage to write on dev.to, I found it too useful to keep to myself :)