👨🏼‍💻

khriztianmoreno's Blog

Home Tags About |

Posts with tag react

Fetching Data in React: A Beginner's Guide

2024-12-09
reactjavascriptweb-development

Imagine building a webpage that displays real-time weather data or a list of products from an online store. How does your React application get this information? The answer lies in data fetching. This process involves retrieving data from various sources (like APIs, databases) and incorporating it into your React components.Sequential Data Fetching:Think of sequential data fetching as a step-by-step process. You fetch one piece of data, wait for it to arrive, and then move on to the next.Example: Fetching user information, then their orders, and finally their address.// Sequential fetching using async/await async function fetchData() { const user = await fetchUser(); const orders = await fetchOrders(user.id); const address = await fetchAddress(user.id); // ... }Parallel Data Fetching:In parallel fetching, multiple data requests are made simultaneously.Example: Fetching user information, orders, and address at the same time.// Parallel fetching using Promise.all Promise.all([fetchUser(), fetchOrders(userId), fetchAddress(userId)]) .then(([user, orders, address]) => { // ... }) .catch((error) => { // ... });Prefetching Data:To enhance the perceived speed of your application, consider prefetching data before it's required. This technique is particularly effective for data that's likely to be needed soon but not immediately. For instance, when leveraging a framework like Next.js built on top of React, you can prefetch the subsequent page and its associated data using their Link component.Example: Fetching post details for the next page.<Link href="/posts/1" prefetch> <a>Post 1</a> </Link>As soon as this Link component becomes visible on the screen, the data for the "Next Page" is preloaded. These subtle optimizations can significantly improve the perceived performance of your app, making it feel more responsive.Conclusion:Choosing the right data fetching pattern depends on your specific use case.Sequential: Simple to implement, suitable for small-scale applications.Parallel: Improves performance for larger datasets, but can be more complex.Prefetching: Enhances user experience by reducing perceived loading times.Key Takeaways:Async/await: A modern way to handle asynchronous operations in JavaScript.Promises: A way to represent the eventual completion (or failure) of an asynchronous operation.Performance: Parallel fetching and prefetching can significantly improve performance.User experience: Prefetching can make your application feel snappier.Additional Tips:Error handling: Always handle errors gracefully to provide a better user experience.Caching: Store frequently accessed data to reduce the number of network requests.State management: Use libraries like Redux or Zustand to manage complex application state, especially when dealing with fetched data.By understanding these patterns, you can build more efficient and responsive React applications.Would you like me to elaborate on any of these concepts or provide more code examples?Profile@khriztianmoren

Why is it so difficult to pass state between client and server components?

2024-03-28
javascriptreactweb-development

The way we represent server components is different.Nothing like what we're used to so far.And because it's so different, it also changes where we handle state, how we handle it, and how we manage to sleep at night knowing that these are all important things we should know since last year, but most of us are completely unaware of.WHY?In fact, server components impact 3 of the most important parts of web development:PerformanceUser ExperienceThe way we, developers, write code and design our applications.It's not something we can ignore or take lightly.As you can see, I've been thinking about it a lot and you've probably been thinking about it too. Every developer who values ​​their keyboard is thinking about it.And there's this specific question... It's kind of a "chicken and the egg" type of question, mainly because they're both questions that get asked a lot.How ​​the heck do I handle state in server components if I don't have access to the state in the first place?Before I give you the answer, let me explain the problem at hand. Consider what happens when a server component requests a new render.Unlike client components where state is preserved between renders, server components don't have that luxury. Like a roguelike game, they always start from scratch.There is no inherent code or mechanism that can make a server component remember state. The backend has all those databases and design patterns and all those complex functions and for what? It can't even handle state.So what do we do? Do we simply use server components on completely static components that don't need any state? While this is a possible answer, it's also an approach that limits the effectiveness and tuning of server components in modern web applications. So, we're ruling it out.Because everything I said above has a drawback.While the backend may not handle client state like the client does, it does handle application state. So, in a way, we can handle state on the server. Just not in the way you think. And, actually, there's not one way.And, actually, there's not one way.There are THREE ways to handle state on the server.Which one we choose depends on what best suits our needs and current situation. And these 3 ways are:Prop drilling from the server to the componentscookiesstate hydrationNow, another million dollar question. Why can't we just handle all the state on the client?This is because server components advocate a separation of concerns. Which in simpler terms means that each part of the application should mind its own business. By decoupling state from rendering, we not only improve performance, but we also gain more control over the user experience.Profile@khriztianmoren

Will you still be using client-side components in 2024?

2024-02-14
javascriptreactweb-development

I love server components. But they're not for every occasion. In fact, using them at each and every opportunity you get is more like tenderizing a steak with the same hammer you used to hammer a pin.That said, there are also some cases where server components fit like Cinderella and her shoe.Dashboards & ReportsIn the case of dashboards and reports, you maximize performance by processing and rendering all the data on the server while still allowing the client to do what it was supposed to do in the first place.If we only use client components, we're offloading more tasks to it and making it perform more tasks than it can potentially handle.If you processed and rendered the data on the client, you'd spend a lot of time waiting around with an ugly spinner mocking you because of all the extra steps the client has to take to achieve the same result.First, you would need to get the data from your endpoint, which in turn would need to get data from the database, which in turn would need to get data from its logs.Not only that, but you also have to wait patiently for the data to arrive at the client, even if it arrives late.And only once it arrives, the client can start processing it and displaying it to the user.That's why, in this case, it's better to have the components locked and rendered directly on the server.And then, the client can get all the widgets its electronic heart desires, all streamed in parallel, which is a much faster and easier way to conduct business.Blog PostsBlog posts are some of the most static content you can find. After all, it's mostly just a bunch of words, in order, with the occasional image, gif, or meme here and there.With server components, you're pre-rendering the content on the server, which is the best case scenario in terms of SEO because it's delivered fast and complete.This use case above is what tends to throw developers off balance and confuse them. Because blog posts are the first thing they think of when it comes to SSR as well. So if they think of SSR and server components when they think of blog posts, it's natural to think that they're both the same thing or can be used interchangeably.Which is completely and utterly wrong and is a sin worthy of burning in hell for eternity, according to my previous blog post.But at the same time it makes sense from the point of view of results. Because although their approaches are very different in practice, the results are quite similar.Server-Side Data FetchingServer-side data fetching is a great way to give your code a security boost in case you otherwise reveal logic or API keys that are supposed to remain hidden or if you are paranoid about every piece of information you hold.You can use this type of data fetching to access not only your database but also any other API you want. All by being sneaky.However, there are cases where server-side components are NOT ideal and should in fact be avoided.High Interactivity RequirementsThis is fancy wording for anything you do something to and get something back. Kind of like Jell-O, but not quite.Something potentially more familiar and more in keeping with web development itself are things like forms and buttons.These components often have to react in some way to your actions, may have their own state, and communicate with other components on the client side, making them the weakest link when it comes to server components.Stateful ComponentsIf you take it as literally as possible and use the definition we've been using so far, there is no way to handle state in a server component.But if you squint, tilt your head a little to the side, defocus a bit, and take a deep breath, you can see that this is only half true.We'll learn what the nuances are another time, but for now let's just say that server components do NOT have access to state. After all, they don't have access to state-related hooks.ConclusionServer components are a powerful tool for specific scenarios in web development. Use them to improve performance and security for data-intensive tasks. But remember, they may not fit every situation, especially for interactive or stateful elements.Profile@khriztianmoreno see you soon

Server Components Vs Server-side Rendering

2024-01-28
javascriptreactweb-development

Did you know that server components and server-side rendering are two completely different things?Image descriptionAnd while they go hand-in-hand in many cases, there are equally many examples where you can and should use just one of them.Image descriptionNow, to be fair, given the online documentation most developers find about server components and server-side rendering, the fact that they assume these two things are the same isn't exactly a surprise.(This also gives them the perfect excuse to avoid server-side components altogether, rather than face the fact that this is something they should already be pretty good at using and will eventually have to learn anyway.)Image descriptionThat said, server-side components have a lot of advantages over server-side rendering, especially when it comes to building larger, more complex applications.Let's talk a bit more about the differences between the two.Server-Side RenderingServer-side rendering renders the page on the server. But obviously that's not really useful, so let's dig a little deeper.Server-side rendering renders the page on the server at request time, meaning that every time a client makes a request to the server — such as when a new visitor comes to your page — the server re-renders the same page and sends it to the client.And while this is great for SEO, since even the most dynamic pages appear static in the eyes of the robots that index them and use them for searches, server-side rendering has a lot of steps between the client making the request to the server and the page finally loading in front of you.First, when the request hits the server, the server statically renders the page and sends it back to the client, where the user gets a version of your page that's devoid of all interactivity.But that's not the only thing the server sends to the client. Along with the static page HTML, the server sends its condolences along with a big bundle of React code that the client will need to run to make the page dynamic again.But what happens when 90% of our page is static?You might think the correct answer is “practically nothing” and you wouldn’t be exactly wrong, but just like in Calculus class, you lose points because this isn’t the answer I was looking for.In reality, there’s still a lot of JavaScript being sent to the client and it needs to be executed without changing much on the page itself.This is a waste of time and data and is one of the main reasons server components were created.(Which also means that if you’re using SSR as an alternative to server components, you’ve hit a big snag and it’s time to change your ways before you get thrown into a “slow performance” jail.)Server ComponentsServer components, like SSR, are rendered on the server, but they have the unique ability to include server-side logic without sending any additional JavaScript to the client, since server components are executed on the server.This means that while in SSR the JavaScript code is executed on the client, in Server Components, the code is executed directly on the server. And the client only receives the output of the code through the server payload, like a baby getting its food chewed up.So, in a nutshell, the difference between server components and server-side rendering is all about when and how the code is executed. In the case of server components, there is no need to send or handle any additional code on the client side because we already run it on the server.The only code needed is if you are tying the server and client components together and the client has to tie the two together.The big benefit of server components is that they offer higher performance because they need less client-side JavaScript and offload all the processing and data retrieval to the server while the client can relax and drink Aperol Spritz until the rendered HTML arrives.At that point, the client simply displays it to the end user and takes all the credit for the hard work done by the server.And while this may seem a bit complex right now, it will all become clearer as you learn more about server components. Which is something that can't really be avoided, as they are becoming more and more popular in use cases like:Having a lot of heavy calculations that need a lot of processingPrivate API access (to keep things secret… secret)When most of the client side is already static and it would be a waste to send more JavaScript to the clientConclusionWhile server components may seem daunting right now, they are mostly something new and strange. Once you get to know them better and learn some of the basics, you'll realize that they are not as complex as they seem.The learning curve is not as steep as you might think and just because they have "sever" in the name, it doesn't mean they have to be something strange and cryptic that we frontend developers should stay away from. In fact, they are quite similar to client components and even more lightweight as they lack things like state hooks, etc.Profile@khriztianmoren

Hacks for effective Fullstack development with React and Node

2023-04-17
javascriptnodejsreact

Today I'm going to show you an optimal workflow for effective development with Node.js and React. If you've ever worked on a project with multiple package.json files, you might know the pain of juggling multiple terminal tabs, remembering which commands start which server, or handling CORS errors.Fortunately, there are some tools available that can alleviate some of these headaches.FullstackMonorepo Setup for React and NodeLet's say we're working on a monorepo with two package.json files: one is in a client directory for a React front-end powered by Create React App, and one is at the root of the repository for a Node back-end that exposes an API that our React app uses. Our React app runs on localhost:3000 and our Node app runs on localhost:8080. Both apps are started with npm startSince we have two package.json files, this means that in order to get our front-end and back-end up and running, we need to make sure we've run npm install and npm start in both the root directory and the client directory. Here's how we simplify this.1. Running two servers at the same timeOne improvement we can make to our development workflow is to add a build tool to run multiple npm commands at the same time to save us the trouble of running npm start in multiple terminal tabs. To do this, we can add an npm package called concurrently to the root of our project.In the root of our project, we will install it as a development dependency.npm install -D concurrentlyThen, in our root package.json scripts, we will update our start script to use them simultaneously.{ "name": "my-app", "version": "1.0.0", "main": "index.js", "scripts": { "start": "concurrently --kill-others-on-fail npm run server npm run client", "server": "node index.js", "client": "cd client && npm start" }, "dependencies": { "express": "^4.17.1" }, "devDependencies": { "concurrently": "^6.0.1" } }Now, we have three npm scripts:npm run server starts our Node application,npm run client runs npm start in the client directory to start our React application,npm start runs npm run server and npm run client at the same time.2. Installing front-end and back-end dependencies with a single commandAnother aspect of our workflow that we can improve is the installation of dependencies. Currently, we need to manually run npm install for every package.json file we have when setting up the project. Instead of going through that hassle, we can add a postinstall script to our root package.json to automatically run npm install in the client directory after the installation has finished in the root directory.{ "name": "my-app", "scripts": { ..., "postinstall": "cd client && npm install" }, }Now, when we install our monorepo, all we need to do to get it up and running is run npm install and then npm start at the root of the project. There is no need to enter any other directory to run other commands.3. Proxy API requests from the backendAs I mentioned earlier, our Node backend exposes the API endpoints that our React app will use. Let's say our Node app has a /refresh_token endpoint.Out of the box, if we tried to send a GET request to http://localhost:8080/refresh_token from our React app at http://localhost:3000, we would run into CORS issues. CORS stands for cross-origin resource sharing.Typically when you encounter CORS errors, it's because you're trying to access resources from another domain (i.e., http://localhost:3000 and http://localhost:8080), and the domain you're requesting resources from is not allowed.To tell the development server to proxy any unknown requests to our API server in development, we can set up a proxy in our React app's package.json file. In client/package.json, we'll add a proxy for http://localhost:8080 (where our Node app is running).{ "name": "client-app", "proxy": "http://localhost:8080", "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, ... }Now, if we restart the server and set a request to our Node app's /refresh_token endPoint (without http://localhost:8080) using fetch(), the CORS error should be resolved.fetch("/refresh_token") .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err));Next time you're working on a monorepo project like this, try these three tips to streamline your development workflow.That's all folks! I hope this helps you become a better dev!Profile@khriztianmoren

React useEffect

2022-09-05
javascriptreacthooks

useEffect is probably the most confusing and misunderstood hook in React. Today I want to clarify that for you.We use hooks all the time at Make It Real and understanding useEffect is crucial if we are going to write modern-style React code.Next, we will see:What is useEffect?How to run an effect on every renderHow to run an effect only on the first renderHow to run an effect on the first render and re-run it when a "dependency" changesHow to run an effect with cleanupWhat is useEffect?The useEffect hook allows us to perform side effects in our function components. Side effects are essentially anything where we want an "imperative" action to happen. This includes things like:API callsUpdating the DOMSubscribing to event listenersAll of these are side effects that we might need a component to perform at different times.Running useEffect on every renderThe useEffect hook does not return any value, but it takes two arguments. The first is mandatory and the second is optional. The first argument is the callback function of the effect we want the Hook to execute (i.e., the effect itself). Suppose we wanted to place a console.log() message inside the useEffect callback.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run for every component render"); }); return ( // ... ); }By default, the effect set in the useEffect hook runs when the component renders for the first time and after every update. If we run the above code, we will notice that the console.log('run for every component render') message is generated as our component renders. If our component ever re-renders (for example, from a state change with something like useState), the effect would run again.Sometimes, re-running an effect on every render is exactly what you want. But most of the time, you only want to run the effect in certain situations, such as on the first render.How to run useEffect only on the first renderThe second argument of the useEffect hook is optional and is a dependency list that allows us to tell React to skip applying the effect until certain conditions are met. In other words, the second argument of the useEffect hook allows us to limit when the effect will run. If we simply place an empty array as the second argument, this is how we tell React to only run the effect on the initial render.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run only for first component render (i.e., component mount)"); }, []); return ( // ... ); }With the above code, the console.log() message will only trigger when the component mounts for the first time and will not re-trigger, even if the component re-renders multiple times.This is much more "efficient" than running on every render, but isn't there a happy medium? What if we want to re-run the effect if something changes?Running useEffect on the first render and re-running it when the dependency changesInstead of making an effect run once at the beginning and on every update, we can try to restrict the effect to run only at the beginning and when a certain dependency changes.Suppose we wanted to trigger a console.log() message every time the value of a state property changes. We can achieve this by placing the state property as a dependency of the effect callback. See the following code example:import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };Above, we have a button in the component template responsible for changing the value of the count state property when clicked. Each time the count state property changes (i.e., each time the button is clicked), we will notice that the effect callback runs and the console.log() message triggers.Running an effect with cleanupAn effect callback runs every time on the initial render and when we specify when an effect should run. The useEffect hook also provides the ability to run a cleanup after the effect. This can be done by specifying a return function at the end of our effect.import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); return () => { console.log("run before the next effect and when component unmounts"); }; }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };In the above example, we will notice that the cleanup function message triggers before the desired effect runs. Additionally, if our component ever unmounts, the cleanup function will also run.A good example of when we might need a cleanup is when we set up a subscription in our effect but want to remove the subscription whenever the next subscription call is to be made, to avoid memory leaks.These are mainly all the different ways the useEffect hook can be used to run side effects in components. I invite you to check out this visual guide to useEffect by ALEX SIDORENKO that illustrates these concepts through a series of GIFs that are both clever and effective, especially for visual learners. There is also a visualization of how first-class functions work if you want more.I hope this has been helpful and/or taught you something new!Profile@khriztianmoreno �

Why Storybook? The component development tool used by over 30,000 projects

2022-08-22
javascriptstorybookreact

Storybook is a tool for developing components and user interfaces faster than ever. Storybook is incredibly versatile: you can use it with a variety of JavaScript libraries and frameworks, not just React. It is available for Vue, React, Svelte, Angular, and Ember.js.StorybookIf you have been developing your components the old-fashioned way, in your text editor or IDE, a tool like Storybook allows you to unlock greater productivity when developing components. Next, you will learn what Storybook is, how it works, and if it is suitable for your team.The problems of developing components traditionallyLet's start by looking at the friction involved with the typical component development process:You receive a task to develop a feature: let's say it's a form on the checkout page.Then, you need to set up the development environment: connect to the VPN, run the backend, run the frontend, etc.Finally, you get to the page where the feature will live.It is cumbersome to navigate between multiple pages, fill out forms, and click buttons every time you need to get to where the feature should be. Sometimes, your components have multiple states, for example, loading, success, and error. It is not always easy to replicate all the states of a component, which leads you to modify the component code just to force a specific state.Storybook isolates your components: easier component debuggingYou may have gone through these situations and encountered the pain involved in this type of component development workflow.Most of the time, while developing, you want to focus on the component you are creating, so other elements on a page become noise. Having a way to quickly access any component or feature, and also being able to simulate all use cases, is incredibly beneficial and saves you a lot of time.Storybook provides you with this type of component isolation so you can work only on the component you have in mind, without having to interact with other components.What is Storybook?Storybook is an open-source tool that helps you develop user interface components in isolation. It runs on your codebase, but separately from your application, so it works like a sandbox, allowing developers not to be distracted by incomplete APIs, unstable data, and other external dependencies. It integrates with frameworks like React, Vue, Svelte, Angular, and others.Think of Storybook as a real book, with an index of pages that links to the user interface components. Each component has stories to tell about itself, and these stories represent the different states of the component's user interface. Regardless of the situation, even if you are offline, you will be able to access that page and easily find and play with the components.Due to its productivity and collaboration advantages, Storybook is used by more than 30,000 open-source projects, especially component libraries. However, many tech companies, such as Airbnb, Atlassian, and JetBrains, are among its users.Who is Storybook for?Some people seem to think that Storybook is a tool only for component library developers, and that is certainly not the case.Storybook helps us build from the simplest and most atomic component, like a button or an input, to complex features or entire pages.Since Storybook helps us summarize the user interface of applications, designers and QA can benefit from it. With Storybook, you can facilitate the development of a design system and share a single language with designers. QA can get an overview and test functionalities in isolation. Storybook can even be used to demonstrate functionality to stakeholders, as if it were a demo.Many companies have made their Storybooks public. They are not only an inspiration but also a learning guide for teams new to Storybook, and you can find a list of public Storybooks here.How it worksFrom a technical aspect, Storybook is essentially a React application that runs on your codebase, separately from your main application. You start it by running a CLI command. It will look for files in your codebase that contain a .stories.* extension, gather all those components, and display them in a nice user interface.Suppose you are creating, for example, a restaurant card. You would have a RestaurantCard.stories.tsx file, which represents the component with mocked properties for each scenario.It is important to note that Storybook does not produce any production code. Your .stories.tsx files are used solely for development purposes.I hope this was helpful and/or taught you something new!Profile@khriztianmoren

Redux explained in a simple and succinct way for React developers

2022-08-10
reactreduxjavascript

Redux is a widely used state management library for React and TypeScript applications. It’s easier than ever to manage state in React thanks to the useState React Hook, as well as the Context API. However, when your codebase grows very large, you’ll need a more powerful and structured state management solution, rather than an ad-hoc one. That’s where Redux can help.ReduxWhy do you need Redux?When working with React, you usually end up with state that is used globally throughout the entire application.One of the approaches to sharing state across the component tree is to use the Context API. We often use it in combination with hooks like useReducer and useState to manage global application state.This approach works, but it can only take you so far. In the end, you have to invent your own ways to manage side-effects, debug, and split state management code into modules so that it doesn't become an incomprehensible mess.A better idea is to use specialized tools. One such tool to manage global application state is Redux.How Redux WorksRedux is a state management framework that is based on the idea of ​​representing the global state of the application as a reducer function.In Redux, to manage state, we define a function that accepts two arguments: state, for the previous state, and action, the object that describes the state update.function reducer(state = "", action: Action) { switch (action.type) { case "SET_VALUE": return action.payload; default: return state; } }This reducer represents a string value. It handles only one type of action: SET_VALUE.If the received action field type is not SET_VALUE, the reducer returns the unchanged state.After having the reducer, we create the store using the redux createStore method.const store = createStore(reducer, "Initial Value");The store provides a subscription method that allows us to subscribe to updates to the store.store.subscribe(() => { const state = store.getState(); console.log(state); });Here, we've passed a callback that logs the state value to the console.To update the state, we dispatch an action:store.dispatch({ type: "SET_VALUE", payload: "New value", });Here we pass an object representing the action (action). Each action is required to have the type field and optionally, payload.Usually, instead of creating actions in place, people define action creator functions:const setValue = (value) => ({ type: "SET_VALUE", payload: value, });And this is the essence of Redux.Why can't we use the useReducer hook instead of Redux?Since version 16.8, React supports Hooks. One of them, useReducer, works very similarly to Redux.It's easy to manage application state using a combination of useReducer and the React Context API.So why do we need Redux if we have a native tool that also allows us to represent state as a reducer? If we make it available throughout the application using the Context API, won't that be enough?Redux offers some important advantages:Browser Tools: You can use Redux DevTools to debug your Redux code. It allows us to see the list of dispatched actions, inspect the state, and even travel back in time. You can toggle through the history of actions and see how the state dealt with each of them.Handling Side Effects: With useReducer, you have to invent your own ways to organize the code that makes network requests. Redux provides the Middleware API to handle that. Additionally, there are tools like Redux Thunk that make this task even easier.Testing: Since Redux is based on pure functions, it is easy to test. All testing comes down to checking the output against the given inputs.Patterns and code organization: Redux is well studied and there are recipes and best practices you can apply. There is a methodology called Ducks that you can use to organize Redux code.Building with ReduxNow that you've seen examples of what Redux does and how it works, you're ready to use it in a real project.Profile@khriztianmoren

A better way to build React component libraries

2022-07-05
reactjavascriptweb-development

Today we'll quickly go over four programming patterns that apply to shared components in React.ReactUsing these allows you to create a well-structured shared component library. The benefit you get is that developers in your organization can easily reuse components across numerous projects. You and your team will be more efficient.Common PatternsIn this post, I show you four API patterns that you can use with all your shared components. These are:JSX children pass-throughReact fowardRef APIJSX prop-spreading cont TypeScriptOpinionated prop defaultsPattern 1: JSX Children Pass-ThroughReact provides the ability to compose elements using the children prop. The shared component design leans heavily on this concept.Allowing consumers to provide the children whenever possible makes it easier for them to provide custom content and other components. It also helps align component APIs with those of native elements.Let's say we have a Button component to start with. Now we allow our Button component to render its children, like this:// File: src/Button.tsx export const Button: React.FC = ({ children }) => { return <button>{children}</button>; };The definition of React.FC already includes children as a valid prop. We pass it directly to the native button element.Here is an example using Storybook to provide content to the Button.// File: src/stories/Button.stories.tsx const Template: Story = (args) => ( <Button {...args}>my button component</Button> );Pattern 2: forwardRef APIMany components have a one-to-one mapping to an HTML element. To allow consumers to access that underlying element, we provide a referencing prop using the React.forwardRef() API.It is not necessary to provide a net for day-to-day React development, but it is useful within shared component libraries. It allows for advanced functionality, such as positioning a tooltip relative to our Button with a positioning library.Our Button component provides a single HTMLButtonElement (button). We provide a reference to it with forwardRef().// File: src/buttons/Button.tsx export const Button = React.forwardRef < HTMLButtonElement > (({ children }, ref) => { return <button ref={ref}>{children}</button>; }); Button.displayName = "Button";To help TypeScript consumers understand what element is returned from the ref object, we provide a type variable that represents the element we are passing it to, HTMLButtonElement in this case.Pattern 3: JSX Prop-SpreadingAnother pattern that increases component flexibility is prop propagation. Prop propagation allows consumers to treat our shared components as drop-in replacements for their native counterparts during development.Prop propagation helps with the following scenarios:Providing accessible props for certain content.Adding custom data attributes for automated testingUsing a native event that is not defined in our props.Without prop propagation, each of the above scenarios would require explicit attributes to be defined. prop propagation helps ensure that our shared components remain as flexible as the native elements they use internally.Let's add prop propagation to our Button component.// File: src/buttons/Button.tsx export const Button = React.forwardRef< HTMLButtonElement, React .ComponentPropsWithoutRef<'button'> >(({ children, ...props }, ref) => { return ( <button ref={ref} {...props}> {children} </button> ); });We can reference our remaining props with the spread syntax and apply them to the button. React.ComponentPropsWithoutRef is a type utility that helps document valid props for a button element for our TypeScript consumers.Some examples of this type checking in action:// Pass - e is typed as // `React.MouseEventMouseEvent>` <Button onClick={(e) => { console.log(e) }} /> // Pass - aria-label is typed // as `string | undefined` <Button aria-label="My button" /> // Fail - type "input" is not // assignable to `"button" | // "submit" | "reset" | undefined` <Button type="input" />Pattern 4: Opinionated DefaultsFor certain components, you may want to map default attributes to specific values. Whether to reduce bugs or improve the developer experience, providing a set of default values ​​is specific to an organization or team. If you find the need to default certain props, you should ensure that it is still possible for consumers to override those values ​​if necessary.A common complexity encountered with button elements is the default value type, "submit". This default type often accidentally submits surrounding forms and leads to difficult debugging scenarios. Here's how we set the "button" attribute by default.Let's update the Button component to return a button with the updated type.// File: src/buttons/Button.tsx return ( <button ref={ref} type="button" {...props}> {children} </button> );By placing the default props before the prop broadcast, we ensure that any value provided by consumers is prioritized.Look at some open source librariesIf you're building a component library for your team, take a look at the most popular open source component libraries to see how they use the patterns above. Here's a list of some of the top open source React component libraries to look into:Ant DesignRainbow UIGrommetProfile@khriztianmorenoUntil next time

Systems Design with ReactJS and Storybook

2020-03-05
javascriptreactstorybookdesign-system

Document and test your React components in isolation using Storybook.Storybook ReactStorybook Reacttl;dr: In this post, we will learn how to set up the necessary infrastructure to build a reusable component design system in React, using Storybook.Let's start by understanding that a design system is a series of components that can be reused in different combinations. Design systems allow you to manage design. If we go to designsystemsrepo.com, we can see the design systems used by some of the largest companies and strongest brands, such as Priceline, Apple, IBM, WeWork, GitHub, and even the US government.Design systems can be a significant productivity multiplier in any medium to large-sized project or company, as we can document our components as we develop them, ensuring a consistent look and feel across all screens, and having a continuous workflow between designers and developers.<iframe width="100%" height="315" src="https://www.youtube.com/embed/guteTaeLoys?si=_8X6KwUOZCjQvwan" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>Throughout this video, we will progressively build a very simple design system that contains a single button, but I will show several of the features that Storybook can offer to improve our development experience and project speed.We will learn to set up the StoryBook used in production by everyone from Lonely Planet to Uber, but at the same time, we will keep it as simple as possible, so we can reuse these APIs for our future needs.I hope this has been helpful and/or taught you something new!Profile@khriztianmoreno �

What is a “side effect”?

2020-02-20
javascriptreactredux

In the previous post, we learned a bit about immutability and why it should matter when writing our code, especially our reducers.This time, I want to talk a bit about side effects and how working with pure functions can help us. However, first, let's see what makes a function pure and why it is closely related to immutability.Immutability RulesTo be pure, a function must follow these rules:A pure function must always return the same value when given the same inputs.A pure function must not have any side effects.“Side effects” is a broad term, but it basically means modifying things outside the immediate scope of that function. Some examples of side effects are:Mutating/modifying input parameters, like giveAwesomePowers (function from the previous post)Modifying any other state outside the function, such as global variables, or document.(anything) or window.(anything)Making API callsconsole.log()Math.random()API calls might surprise you. After all, making a call to something like fetch('/users') might not change anything in your UI.But ask yourself this: if you called fetch('/users'), could it change anything anywhere? Even outside your UI?Yes. It will create an entry in the browser's network log. It will create (and perhaps later close) a network connection to the server. And once that call reaches the server, all bets are off. The server could do whatever it wants, including calling other services and making more mutations. At the very least, it will probably place an entry in a log file somewhere (which is a mutation).So, as I said: “side effect” is a pretty broad term. Here is a function that has no side effects:You can call this function once, you can call it a million times and nothing will change. I mean, technically, this satisfies Rule 2. Calling this function will not directly cause any side effects.Also, every time you call this function like add(1, 2) you will get the same answer. No matter how many times you call add(1, 2) you will get the same answer. That satisfies Rule 1: same inputs == same outputs.JS Array Methods That MutateCertain array methods will mutate the array they are used on:push (add an item to the end)pop (remove an item from the end)shift (remove an item from the beginning)unshift (add an item to the beginning)sortreversesplicePure Functions Can Only Call Other Pure FunctionsA possible source of trouble is calling an impure function from a pure one.Purity is transitive and it's all or nothing. You can write a perfectly pure function, but if you end it with a call to some other function that eventually calls setState or dispatch or causes some other kind of side effect… then all bets are off.Now, there are some types of side effects that are “acceptable”. Logging messages with console.log is fine. Yes, technically it is a side effect, but it is not going to affect anything.A Pure Version of giveAwesomePowersNow we can rewrite our function keeping the Rules in mind.giveAwesomePowers — Pure functiongiveAwesomePowers — Pure functionThis is a bit different now. Instead of modifying the person, we are creating a completely new person.If you haven't seen Object.assign, what it does is assign properties from one object to another. You can pass it a series of objects, and it will combine them, from left to right, while overwriting any duplicate properties. (And by “from left to right”, I mean that running Object.assign(result, a, b, c) will copy a into result, then b, then c).However, it does not do a deep merge: only the immediate properties of each argument will be moved. Also, most importantly, it does not create copies or clones of the properties. It assigns them as they are, keeping the references intact.So the above code creates an empty object, then assigns all the properties of person to that empty object and then assigns the specialPower property to that object as well. Another way to write this is with the object spread operator (spread):giveAwesomePowers — ES6 || spreadgiveAwesomePowers — ES6 || spreadYou can read this as: “Create a new object, then insert the properties of person, then add another property called specialPower”. As of this writing, this spread syntax is officially part of the JavaScript specification in ES2018.Pure Functions Return Brand New ObjectsNow we can rerun our experiment from before, using our new pure version of giveAwesomePowers.The big difference is that person was not modified. Mafe has not changed. The function created a clone of Mafe, with all the same properties, plus the ability to become invisible.This is kind of a weird thing about functional programming. Objects are constantly being created and destroyed. We did not change Mafe; we created a clone, modified her clone, and then replaced Mafe with her clone.I hope this has been helpful and/or taught you something new!Profile@khriztianmoreno �

What is immutability?

2020-02-10
javascriptreduxreact

Immutability in React and ReduxImmutability can be a confusing topic, and it appears everywhere in React, Redux, and JavaScript in general.You may have encountered errors where your React components do not re-render, even though you know you have changed the props, and someone says, "You should be making immutable state updates." Maybe you or one of your teammates regularly writes reducers in Redux that mutate the state, and we have to constantly correct them (the reducers, or our teammates 😄).It's complicated. It can be very subtle, especially if you're not sure what to look for. And honestly, if you're not sure why it's important, it's hard to care.

Introduction to Apollo Client with React for GraphQL

2020-01-30
javascriptreactgraphqltutorial

GraphQL has become popular recently and is likely to replace the Rest API. In this tutorial, we will use the Apollo Client to communicate with GitHub's GraphQL API. We will integrate Apollo Client with ReactJS, but you can also use it with other platforms (VueJS, Angular, etc).

Flux Standard Action (FSA)

2020-01-20
reactjavascriptreduxtutorial

It is a lightweight specification that defines the structure of an action, to be implemented in libraries that use the Flux pattern or architecture.Compliance with FSA helps developers create abstractions that can work with different implementations of Flux.Flux Standard Action — ExampleFlux Standard Action — ExampleIt all started after Facebook published its architecture/pattern Flux, many libraries implemented the Flux philosophy, Redux was one of them.Flux can be divided into several concepts Dispatcher, Store, Action, and View. But in this post, we are going to learn about the Action part and how to work with them in a more standardized way, so later we can use other libraries that implement the FSA philosophy.Before delving deeper into today's main topic, let's get to know the concept of Action and how it is defined by flux:Actions define the internal API of your application. They capture the ways to interact with your application. They are simple objects that consist of a “type” field and data.The specification would lead to the following object:{ type: 'ADD_TODO', text: 'TODO content' }The only problem with this simple example is that the developer can choose any property name for the values. All the following names are valid: title, name, text, todoName, etc. It is impossible to know what properties to expect from ADD_TODO in the Redux reducer.It would be much easier to work with Flux actions if we could make certain assumptions about their shape. Maybe defining a minimum common standard for these patterns would allow us to have the necessary abstraction to communicate our actions with the reducer. This is something that Flux Standard Action (FSA) comes to solve.To go into a bit more detail about FSA, it is necessary to start from the following premise that Flux Standard Action provides us about actions:An action MUST:be a plain JavaScript object.have a type property.An action MAYhave an error property.have a payload property.have a meta property.An action MUST NOT include properties other than type, payload, error, and meta.But then what does each of these properties that our JavaScript object can contain mean?Let's see each of thesetypeThe required property type identifies the nature of the action that has occurred to the consumer, type is a constant of type StringpayloadThe optional payload property MAY be any type of value. It represents the action's payload. Any information about the action that is not the type or the status of the action should be part of the payload field.By convention, the payload SHOULD be an object.errorThe optional error property MAY be set to true if the action represents an error.An action whose error is true is analogous to a rejected Promise. By convention, the payload SHOULD be an error object.If the error has any value other than true, including undefined and null, the action MUST NOT be interpreted as an error.metaThe optional meta property MAY be any type of value. It is intended for any additional information that is not part of the payload.The Flux Standard Action (FSA) concept is used by some libraries that can help us reduce the repetitive text we have to create for our actions.Librariesredux-actions — a set of helpers to create and handle FSA actions in Redux.redux-promise — A middleware that supports FSA actions.redux-rx — RxJS utilities for Redux, including a middleware that supports FSA actions.I hope to have the opportunity to give an introduction on how to reduce Redux boilerplate with Redux-Actions in a future occasion.I hope this has been useful and/or taught you something new!Profile@khriztianmoreno �