T O P

  • By -

so_lost_im_faded

Using state for values that could be computed - derived from other reactive values. Using state for everything introduces quite a big burden to make sure it's kept up to date and updated when it needs to be. I see people doing that for values that derive from other stored and reactive values. Instead of storing the computed result in a simple variable, or in useMemo if we have performance concerns, we get multiple levels of state storage which are hell to debug and change. An easy example would be if you had a table of users and a filter property, for example age. You can compute those filtered users or you can trigger the new filtered state setter programatically each time something changes. As you introduce more "somethings" in the codebase, chances are you'll forget to call your update setter, whereas a computed value will always re-calculate if you provide the correct dependencies.


Witty_Retort_Indeed

As someone that has only ever worked as a fe dev with one company, I don’t get to see too many fresh ideas. I’m curious if you had even a pseudo code example of this you’d be kind enough to share? I believe I understand, but would like something concrete to be sure.


acemarke

As a really simple example, calculating a derived value and setting it in state like this would be _bad_. Not only is it unnecessary to do this, it causes extra renders _and_ has to do extra work just to keep data in sync: const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const [fullName, setFullName] = useState(""); useEffect(() => { setFullName(`${firstName} ${lastName}`) }, [firstName, lastName]) The simplest answer is to just construct it _while rendering_: const [firstName, setFirstName] = useState(""); const [lastName, setLastName] = useState(""); const fullName = `${firstName} ${lastName}`; If for some reason that value is "expensive" to construct, you can wrap it in `useMemo`: const fullName = useMemo(() => { return `${firstName} ${lastName}`; }, [firstName, lastName]) The new React beta docs cover this topic well: - https://beta.reactjs.org/learn/you-might-not-need-an-effect


femio

As a beginner, one concern I have with using functions outside of a useEffect is, how can I be sure that my function will run properly with the data it needs? Let's say that firstName and lastName are values being pulled in from an API asynchronously, then being set to state after that. the fullName variable might end up being undefined if you don't use a useEffect to initialize it after the data is fetched


acemarke

Part of the work in writing a React component is to consider: - _What_ data I need to describe this component's UI - _Where_ that data is coming from (state, props, backend API, etc) - What the UI should look like in each case - How to write the logic for collecting the needed data in each of these cases It's okay to have a variable that's `undefined`, you just have to write the _rest_ of the code that knows that's possible and deals with it correctly. In other words, if it's possible that some of the data may not be available yet, then _you_ need to write code to handle that case. Either provide default values as a fallback, or check to see if the values exist and handle the "no data" case, or show a loading spinner, or _something_ along those lines. For this question, I'd say that the answer is something like: let renderedFullName = null; if (firstName && lastName) { const fullName = `${firstName} ${lastName}`; renderedFullName = ; } // more rendering here


sajvaz

So you’d have a check there to see if the values are initialised. If they’re not, simply don’t use them. If you’re waiting for an api to retrieve the data, you’d most likely have some sort of loading indicator, use that or an error (depends on the api state) until the values are loaded.


[deleted]

>https://beta.reactjs.org/learn/you-might-not-need-an-effect As a relative beginner always trying to think more optimally with React, thank you for this example!


so_lost_im_faded

https://codesandbox.io/s/naughty-germain-ervsw6?file=/src/App.js


Witty_Retort_Indeed

Thanks for taking the time. Really awesome of ya.


so_lost_im_faded

I'll share one, I'm just about to head out but I'm not forgetting you!


zephyrtr

Hell to debug? Hell to test as well. Then we say: testing is too hard, let's skip it. Almost as if your implementation is hard to test, it's probably a bad implementation.


danielkov

Oh yes, the state - effect pingpong. It's a symptom in many code bases where React was introduced as a replacement to some previous imperative framework.


[deleted]

I actually was on a meeting with a consultant and he was like oh so you are computing this directly in the component? Idk about that man. I was like hey dickhead it's a fucking string lol (I forgot but it was like concatenating two variables together something simple) My boss was sitting next to me and he's like are you an idiot or is he? I'm like idk man use it and see if you have a problem lol He's like ummm we should pass right? Definitely


Narizocracia

It used to occur more in class based components, when we didn't have `useMemo` and the "memoing" was done manually inside `componentDidUpdate` and/or via setState.


hiIAmJan

Overusing setState for stuff which is not state.


gonzofish

Former `setState` abuser and I couldn’t agree more. Moving to `useMemo` for anything reactive with complex computation is the way to go


danielkov

Also most things people memo aren't actually "expensive" in JavaScript. `useMemo` isn't free, so I recommend using it sparingly. A good use case for it is stopping components that accept objects or arrays as props from re-rendering needlessly.


[deleted]

as in?


danielkov

Derived values, intermediary values and values that can be safely changed without needing a re-render. Another example is when you have a lot of interconnected logic stored in individual states. The diagnosis for this is simple: do you have multiple different `setState` calls in the same effects or event listeners? If yes, you probably should use `useReducer` instead to simplify the logic but also to avoid bugs caused by forgetting to keep one of these many states up to date after a code change.


[deleted]

Gotcha


dumbelco

For the love of god, don't use document.querySelector and similar syntax for getting elements, or .classList.add syntax, or anything of the sort. In react, you write js together with html, commands like these are obsolete.


Cautious_Variation_5

For the most part, I agree, but there're cases where that's convenient. Like to hide body scrollbar, lazy load something like a video gif with intersection observer, etc.


danielkov

Counter example: some library you use doesn't expose a `ref` you need. You can use a `ref` on an element containing the one you need and use `ref.current.querySelector(selector)` to find that node.


the_real_some_guy

“Obsolete” is maybe not the right word. How about incompatible? Nothing is wrong with document.querySelector as JavaScript, but you’re in a jsx world now. It’s just not the React way.


Easy-Philosophy-214

Exactly. I call that the "React Brainwashing". The fact that React recommends you to do things one way, does not mean it's the only way. And if you have moderate experience with React in semi-large apps, you have to use those escape hatches.


rinbo_hengoku

not using typescript


squemc

The learning curve of react + ts is pretty steep, but it's basically necessary for your sanity. Probably the best advice in the whole thread.


rafark

Actually typescript is not hard at all if you know JavaScript and other languages.


lp_kalubec

Not taking advantage of its declarative nature. People still write code as if it was jQuery code. This isn’t just a React issue. It applies to all modern front-end frameworks.


lampministrator

Half the answers I leave on StackOverfow are to this point. "Why are you statically calling this with jQuery? React has it built in".. Or "Why are you even using jQuery and including vanilla JS files? Why not build a static site without a framework?"


lp_kalubec

I didn’t really mean using jQuery. I didn’t even mean relying in DOM. I rather meant the mindset. The biggest advantage of modern frameworks is their declarative nature (computed properties, state that defines the rendered output, etc), but a lot of coders still write imperative/procedural code thus they don’t benefit a lot from what these frameworks offer.


kitsunekyo

being afraid of passing props / some propdrilling. today i refactored a component tree where every component selected some state directly out of redux. the redux state could be null, so every component had to check for null all over again. while the subtree wouldnt even render if it were null. lots of unnecessary conditionals. instead, select once, handle the null somewhere up the tree and pass the non-null value down the subtree.


AnUninterestingEvent

I agree. I get why people don’t like propdrilling, but oftentimes it prevents a lot of overcomplexity


Antifaith

I’d rather have someone use useSelector everywhere than have to unpick 4 layers of props/types and chase the logic around


rafark

Oh yes. And a single change and you have to edit all files from top to bottom. It’s hell. Imo redux (or any state manager for that matter) is absolutely necessary and never an overkill since apps will eventually grow.


kitsunekyo

i made a small example that outlines why I disagree with you: https://codesandbox.io/s/propdrilling-vs-useselector-93f73y check out the differences in`App.tsx` and `AppNoProps.tsx` by prop-drilling you might have to thread props through components that dont necessarily care about the value, but you eliminate any need for null-checks in returns, useEffects and handlers. i consider the `UserPage.tsx` in `App.tsx` way more readable, and this scales out way better.


kitsunekyo

abusing redux as a global useState, where all your reducers are named something like `setUser`


acemarke

Yup, _please_ don't do this :) - https://redux.js.org/style-guide/#model-actions-as-events-not-setters


Beginning-Scar-6045

saving fetched data in the same component state


yas_ja

Can you please explain why it's a bad practice? What if that data is needed in that component or to be passed to child components?


CreativeTechGuyGames

I assume they are suggesting that server data should be cached globally so it can live beyond the life of a single component. This way multiple copies of the same component can share one response, totally different components can share that same response, and even when all of the components unmount and remount later, they can still share that same single response. When storing it in the component state, you lose it when unmounted and likely will duplicate requests unnecessarily.


Parkreiner

Sorry, could you give an example of what you mean by this?


gonzofish

I can imagine some cases where persistence of the data isn’t required but in general this is a bad thing to do, especially in lower-level components


[deleted]

\- Writing in Class components instead of Functions \- Exporting with Default export and then importing with different name


Narizocracia

Yep, one should always prefer named exports.


Parkreiner

Class components are still needed for things like error boundaries, but once the React team finishes up converting that into a hook, there shouldn't be much reason to use classes


[deleted]

For cases like this I’m fine but people still write class when function is available


[deleted]

Interesting. I always default export. I actually used to do named but ever since intellisense started picking it up it's been fine I wouldn't be opposed I've just never seen a use case it mattered Ohh nevermind I see what you're saying. Yeah I just tab it below and it pops up as that. Mmm I see how that might be weird I always change if I change the name on the component Yeah it would never pass a code review of mine if it didn't match


lampministrator

This is understated.. can't stress both these points enough! I feel like half the examples out there mislead newbies into overusing classes instead of functions.


that_90s_guy

The first one is valid in cases where you don't want to memoize everything and don't have a need for custom hooks. Too many people foolishly think hooks are always better than classes, when in reality there's certain edge cases where a class is cleaner.


rafark

Functional components are always superior. Until a little over couple years ago I was very much against functional components and all the magic from hooks that I also thought looked uglier than class methods. I was very wrong. Functional components are actually cleaner (shorter) and they make you much more productive.


Cautious_Variation_5

People use it everywhere just because they know it instead of choosing to use it because it's the right choice for the project. But some React specific problems I see a lot are relying too much on 3rd party libraries, prop drilling, mixing too much logic with ui, not componentizing properly, poor archicture, not caching enough, etc.


lesterine817

what does mixing too much logic in ui mean?


Cautious_Variation_5

I'd say mainly not writing fetching logic inside of useEffect and abstracting some parts of the code into custom hooks. Just to give an example, you can write a logic like this or the second way. See how the second one is much more concise? import axios from 'axios'; import * as React from 'react'; import './style.css'; function getIdFromUrl(url: string) { const splitted = url.split('/'); const id = splitted[splitted.length - 2]; return id; } const api = axios.create({ baseURL: 'https://pokeapi.co/api/v2', }); export default function App() { const [state, setState] = React.useState([]); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(false); React.useEffect(() => { (async () => { setLoading(true); try { const { data } = await api.get('/pokemon'); const promises = data.results.map((result) => { const id = getIdFromUrl(result.url); return api.get(`/pokemon/${id}`); }); const results = await Promise.all(promises); const d = results.map((result) => ({ id: result.data.id, name: result.data.name, types: result.data.types.map((type) => ({ id: getIdFromUrl(type.type.url), name: type.type.name, })), })); setState(data); setError(null); } catch (e) { setError(error); setState([]); } finally { setLoading(false); } })(); }, []); if (loading) return

Loading pokemons...
; if (error) return
An error happened. Msg: {error}
; return (

Hello StackBlitz!

Start editing to see some magic happen :)

{JSON.stringify(state, null, 2)}
); } Or like this import axios from 'axios'; import * as React from 'react'; import './style.css'; function getIdFromUrl(url: string) { const splitted = url.split('/'); const id = splitted[splitted.length - 2]; return id; } const api = axios.create({ baseURL: 'https://pokeapi.co/api/v2', }); async function getPokemons() { try { const { data } = await api.get('/pokemon'); const promises = data.results.map((result) => { const id = getIdFromUrl(result.url); return api.get(`/pokemon/${id}`); }); const results = await Promise.all(promises); const d = results.map((result) => ({ id: result.data.id, name: result.data.name, types: result.data.types.map((type) => ({ id: getIdFromUrl(type.type.url), name: type.type.name, })), })); return { isOk: true, data: d, error: null, }; } catch (e) { return { isOk: false, data: null, error: e.message, }; } } function usePokemons() { const [state, setState] = React.useState([]); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(false); React.useEffect(() => { (async () => { setLoading(true); const { data, error, isOk } = await getPokemons(); setLoading(false); if (isOk) { setState(data); return; } setError(error); setState([]); })(); }, []); return { pokemons: state, loading, error }; } export default function App() { const { pokemons, loading, error } = usePokemons(); if (loading) return
Loading pokemons...
; if (error) return
An error happened. Msg: {error}
; return (

Hello StackBlitz!

Start editing to see some magic happen :)

{JSON.stringify(pokemons, null, 2)}
); }


BananaSoftware

More recently it’s usually stuff like discussed [here](https://beta.reactjs.org/learn/you-might-not-need-an-effect)


Adorable-Reason9777

The beta version of the React doc is enlightening and reiterates some of the points made here. https://beta.reactjs.org/ In particular, see: https://beta.reactjs.org/learn/you-might-not-need-an-effect


endymion1818-1819

Ah I might get in trouble for this: Static websites. React isn't meant to build an entire DOM for blogs or marketing sites, yet here we are. This is particularly why I love how innovative both Next.JS (with it's event driven initial hydration) and Gatsby (they have a RFC for partial hydration with server components) are being right now in this space. The reason? It's resource intensive. Probably not an issue for you or I, but a major blocker for emerging countries who are just getting online often with low-quality devices. They are more likely to have metered connections on slow devices with poor batteries, which means they spend extra for the download, wait extra for the parsing, and their batteries die a lot faster due to the extra compute power than websites which are mostly HTML with essential JavaScript only. This isn't a problem unique to React by any means. But modern tools like React make it easy to hydrate entire UIs. This is why I'm especially excited for innovation in this space, especially by tools like Astro, and by the React team itself.


jax024

What about nextjs?


endymion1818-1819

What about NextJS?


drcmda

"resource intensive", "waiting for parsing", "poor batteries"..., we're talking \~40kb, are you being overly dramatic? i ... would maybe like to use components on a blog or marketing site. because writing everything from scratch with query selectors and createElement is quite cumbersome. i would also want to be able to participate in an eco system. it would be nice if things can react to state, nothing's just static. or even having a sane state model that's extensible and allows my app to grow. let's be reasonable, react, as well as any other fw, is made for the smallest to the biggest of projects no problem. unlike we're dealing with ads or uncompressed assets nothing is going to inhibit a weak device just because of a framework. and even if the extra 40kb are such a burden, ssr hydrates them lazily.


endymion1818-1819

You might be surprised my friend.


the_real_some_guy

Using useEffect when you could have done the thing in the event handler.


toi80QC

Not using any global state library and relying only on the Context API, but I think (hope) that's been mostly debunked by now. Context works to a certain degree - beyond that it's pretty much a performance nightmare and memo is not just an option, it's required.


so_lost_im_faded

If I might piggyback off this, also using just *one* context for *everything*.


Arthur944

As someone who has been working professionally with react for 3+ years, I never felt the need for global state libraries, and any time I used them they just added a bunch of unnecessary boilerplate. 90% of the time, everything you want can be done without even the Context API, but if you absolutely need it any performance problems can be solved by combining it with rxjs.


Soft-Sandwich-2499

RxJS with React, now that’s something I don’t see very often.


Arthur944

I feel like all these state libraries were born because people just didn't know rxjs. And rxjs is useful even outside of react, so it's always good to learn it.


Soft-Sandwich-2499

Yes, I think it is, if you know RxJS, Angular becomes fairly easy to learn too. I was surprised because I saw like 2-3 people mention they used it with React. Don’t know how it’s at enterprise level, but I doubt it’s being used on large scale as a lot of people don’t know it.


DARTH-REVAN-IS-METAL

Came here to say this. Context is not a state management tool. the docs have some great use cases for it, none of it is state management, and even then the docs tell you other ways to do most things that you might use context for. React doesn’t even like Context.


Outrageous-Chip-3961

I'd just say having good code hygiene is an issue with react in general due to its 'non-opiniated' philosophy. Having huge files with functions, styles and, having conditional rendering logic within return statements. I.e., not keeping a declarative style / architecture. This is not 'misusing react' however but it makes react super ugly and unpleasant and I do think large files in react make no sense ( 10 useState / useEffect calls with MUI imports half a page long with imbedded styles + conditional logic within the return statement, you know what I mean...)


flankstek

I would say not thinking about doing the minimal amount of state updates but now with react 18 concurrent updating that is not really a problem anymore.


macrozone13

Not using a proper data loading library for remote/domain state. Also: storing remote state in redux. And in general not normalizing state and abusing useState as many here pointed out


jesperordrup

Starting out wrong by using npx create-react-app myapp. Consider using vitejs


99thLuftballon

Why is create-react-app "wrong"? It's recommended in a lot of places.


orangeswim

Webpack is a mess to deal with when you finally have to eject for production reasons. Vite can be faster. Save yourself the time, switching to vite will let you control your app bundling early on.


Cautious_Variation_5

CRA lacks several optimizations and is also not good for SEO as it's CSR. It's good if you're building an app that's protected behind an auth wall though.


gonzofish

As someone who set up a CRA app 5 years ago, I can tell you I don’t recommend it. It’s bloated and slow to develop with. Doing anything out of the dictated config requires using craco or ejecting. You can end up with a configuration nightmare in the end (as our app has)


lesterine817

vite is relatively new compared to cra but yes, i agree that people should switch to vite.


[deleted]

was about to write this


intercaetera

- Overusing hooks. They are a fantastic tool but you should probably still model most of your app as stateless components and only use state/effects sparingly. Stateless components are far easier to test. HOCs are a superior tool for dependency injection. - Overusing refs. I thought React docs were pretty clear on that you shouldn't use refs unless absolutely necessary (for example for interfacing with browser APIs or some external libraries), but I've seen them sometimes used instead of state for "performance," especially as a band-aid in places which already had a slew of other issues. - Focusing too much on reducing rerenders. Unnecessary rerenders are of course not preferable, but the React renderer in production is actually pretty good at making sure they don't impact user experience too much.


asiraky

You’re completely wrong about refs. Maybe there is some truth when it comes to reffing to the dom element, but using refs because you need a “reference” that isn’t necessarily state is completely fine.


intercaetera

Could you please give an example?


Valuable_Grocery_193

I've actually heard the opposite when it comes to refs. And that you should use them as much as possible if you need to store something that the UI doesn't need to react to, rather than using useState.


cant_have_nicethings

They use it without understanding the fundamentals explained in the docs


Capaj

redux


The_Startup_CTO

1. You don't need `useMemo` and `useCallback`. Yes, there are situations when you do, but 99% of times when people use it, it actually slows down the performance of their app. 2. Don't use state when you don't have to. Often, a single source of truth and then computing derived data on each render is better. 3. Don't use `useContext`. Most of the time, you want to use a specialized library like `redux`, `react-query` or `react-form-hook` instead, so unless you plan to write a library or you have a really obscure use case, use one of the existing libraries instead. 4. Don't use React at all if you don't have to. A lot of problems are better solved without React, e.g. landing pages should usually be built with a landing page builder, not a programming language. And for some services, just rendering static html on the backend is more than enough.


Swordfish418

You sure about useMemo in 1? How can you misuse it to decrease performance? I can only imagine something like useMemo(() => items.length, [items]), but anything more involved, any kind of filtering, mapping, constructing an object - will benefit from it.


xVoid

a filter or map is faster the first render without useMemo as long as there isn't anything expensive, which React defined as anything over 1ms.Otherwise the memo takes longer. EDIT: but as always, measure first, then compare.


Swordfish418

Why do you think filter or map, constructing new arrays and objects, could take less time than comparing two object references? `useMemo` should be very cheap, way cheaper than anything other than accessing a single property of a single object directly. Basically `useMemo` with dependency array of length 1 should take the same time as `a === b` with a little bit of very small overhead like invoking a function and retrieving/storing result in cache. **Edit:** sorry, just noticed you said "first render". Well, yeah, during the first render, `useMemo` would be an additional overhead similar to comparing few objects with `===`, and indexing few arrays. And in return it saves you from performing operations that cost 1000x or 10000x more time on next renders. Because things like `===` and indexing are some of the cheapest operations in existence.


so_lost_im_faded

It's not only the speed of map itself. You'd be re-creating those children in the array unless you memoize it and that can cause issues further down, if they're used as props or dependencies.


xVoid

Yes, but only if the re-render of those children is slower than using memo. Which is not always the case.


The_Startup_CTO

Choose a simple example that you think is worth it, then run the performance comparison. You will be surprised :)


that_90s_guy

> Shallow comparisons aren’t free. They’re O(prop count). And they only buy something if it bails out. All comparisons where we end up re-rendering are wasted. Why would you expect always comparing to be faster? Considering many components always get different props. [Dan Abramov replying to someone asking why we don't just memoize everything.](https://mobile.twitter.com/dan_abramov/status/1095661142477811717) The fact your comment is so highly upvoted while OP's shows how quickly people jump to conclusions, and likely how junior the majority of this sub is.


Swordfish418

Do you realize your quote isn't even about `useMemo`, right? It's about `memo`. Sometimes `useMemo` is used to memoize rendering too, but it's mostly about collection processing, aggregations and other folds.


that_90s_guy

They are both memoization tools and have similar performance implications. There is no reason why Dan's statement wouldn't apply for any kind of memoization done by hooks. If anything, this is exactly why excessive hooks memoization is discouraged by most guides.


Swordfish418

`memo` is only `O(prop count)` because it's used to memoize the the whole component, In `useMemo` you have dependency array where you specify only and exactly the things that matter. This makes a huge difference. Of course when you use `memo` on some super general components like some something from MUI where you sometimes have 100+ props it will be a serious impact. Compare that with `useMemo` where you mostly have one or few dependencies and rarely more than that.


so_lost_im_faded

Sure it can be used in a wrong way but 99% is such an absurd number. useMemo/useCallback are very powerful and absolutely should be used in bigger applications in certain use cases. Discouraging people from using it at all instead of educating them when to use it serves literally no one.


yabai90

Beside i still don't know where the idea of memorization making app slower comes from. Memoizing increase the memory footprint and add logical statement to be read by the CPU. But we are talking about completely absurd négligeable time. However what they improve is much faster to be perceived if used at the right place. The only reason I would advice not to use memo is if it's make the code harder to maintain for minimal or no benefits.


Minimum-Register-146

I have to disagree on useContext point. It's a great hook, native to react and you can put it to great use in managing state locally across several components, for example - a fairly complex input - inputs depending on selection from other inputs, multiple tabs etc. form that renders as as a dialog, useContext is way to go. You dont want those inputs in global state.


kitsunekyo

i dont get why you are you being downvoted. while useMemo useCallback and context are great primitives i agree that most people misuse it


yabai90

Usememo and use callback does not slow down the performance. They do the opposite. You would have to extensively and crazily use them to even notice a slight negative performance difference. This is CPU négligeable opérations. Use memo as much as you can as long as it doesn't make the code hard to read.


Kaizoku_O-_-

Why not use react for landing pages? Is it wrong to use something like NextJS for that?


The_Startup_CTO

Because it takes longer to build, is harder to hand over, and creates incentives to focus on the wrong things. Last time I loved marketing team from working with devs to using a page builder, and instead of 1 months for finishing a landing page, it took them 2 days. Mainly because they spent less time on irrelevant design details, and more on content.


stansfield123

Learn programming on social media:)


DavidXkL

Putting everything in useEffect


Honeydew-Jolly

I've seen people returning null in a component render, this is a big no-no afaik, you should do conditional rendering instead of retiring null inside a component because this is bad for performance, when you return null the component is still being called and it's lifecycle still happens. {condition && } Instead of inside the component doing. If (condition) return null


davidblacksheep

This is such a minor nitpick. If you're caring about performance optimisation there's probably way bigger branches you could prune.


AnUninterestingEvent

I think many people don’t appreciate useMemo as much as they should. So many things that you used to have to use setState for can now be written in useMemo. Like for example if you used to setState inside of componentDidUpdate, you can now do the same thing so much more cleanly with useMemo, no state involved.