Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

4 Ways to Show Tooltips in React with react-tooltip, Material UI, Bootstrap, or Semantic UI

Tooltips are a great way to provide additional context for elements in your application. In this article we will see how to add tooltips to your React applications using four different libraries: React Tooltip, Material UI, Bootstrap, and Semantic UI.Tooltip is a simple element that can be tricky to implement. You need to consider positioning, responsive layouts, and various browsers support. Fortunately, there are libraries that do that for you. We will look at several popular options for showing tooltips in React applications: React Tooltip , Material UI , Bootstrap , and Semantic UI . For this article, we assume that you're familiar with React components and how to use props and state to control them. All the libraries we're going to review provide great tooltip components. With all options, we can add a tooltip, define content for it, configure its position and styling. So the question is how to select the right one for your project? React Tooltip is a small library that provides only a tooltip component. Other options are large UI libraries with lots of different components. If you only look for the tooltip component for your React application with no need for other elements, React Tooltip would be a great option. In case if you're looking for multiple elements with a unified look, then you can select from Material UI , Bootstrap , and Semantic UI . The UI framework to use would depend on your preferences for a particular project. React Tooltip provides a tooltip component. We start by adding React Tooltip to a project: After that, we can use the ReactTooltip component to display tooltips: In this example, we start by importing the ReactTooltip component. We use ReactTooltip to render the content of the tooltip. We specify the id property for the tooltip and a content. The place and effect properties define the position of the tooltip. Next, we need to mark an element for which we'd like to display a tooltip. This is done with the data-tip and data-for custom attributes. We specify these attributes for the <button> element, but you can display tooltips for any element. The data-tip attribute helps React Tooltip to find an element. The data-for attribute contains the id of the ReactTooltip component that we've declared. There are additional options that allow controlling the position, events, and styling of a tooltip. You can find the API description in the GitHub repository and additional examples on the official site. Material-UI is a collection of React components based on Material Design from Google that you can use in your React applications. It includes the Tooltip component that we can use to show tooltips. Here's how we can show a simple tooltip with Material UI: We start by importing Button and Tooltip components. Next, we wrap the button that we want to show a tooltip for with the Tooltip component. We specify properties for the tooltip: the title property defines the text to display and placement specifies the position. You can find more tooltip examples on the official site. Bootstrap is one of the most popular frameworks for building web applications. There is a set of components that allow displaying overlays, tooltips, and popovers. Here's an example of the Bootstrap tooltip using the React Bootstrap : We start by importing Button , Tooltip , and OverlayTrigger components. We also import the Bootstrap CSS file for the default theme. In Bootstrap the Tooltip component does not position itself, it uses the OverlayTrigger component for that. We wrap the Button with the OverlayTrigger component to define that we'd like to show a tooltip for the button. The placement property of the overlay specified the position of the tooltip, while the overlay property defines the content to render for the tooltip. The renderTooltip function specified for the overlay property returns the Tooltip component with tooltip's content. More tooltip examples are available on the official site. Semantic UI is another popular UI framework that we can use in React applications. It contains its own tooltip component as well. Here's an example of a tooltip using Semantic UI Popup component: We start by importing the Button and Popup components. We also import the Semantic UI semantic.min.css file for default styling. We're using the Popup component to render the tooltip. The trigger property defines the component for which we'll provide a tooltip, the position property defines the position of the tooltip. The content specified inside the Popup component will be used as a tooltip's content. Tooltips are a great way to show additional content for UI elements. In this article, we've seen four ways to add tooltips in React applications. You are free to select the one that better works for your application.

Thumbnail Image of Tutorial 4 Ways to Show Tooltips in React with react-tooltip, Material UI, Bootstrap, or Semantic UI

Quick Introduction to Internationalization in React with react-intl

In this article we will see how to internationalize React applications with the react-intl library. React Intl helps to translate React applications. It provides components and API to format strings, dates, and numbers.Supporting multiple languages in an application is a great way to make it appealing to an international audience. At the same time, supporting multiple locales with different pluralization rules and formatting for dates and numbers can become a complex task. React Intl is the library that simplifies the internationalization of React applications. For this article, we assume that you're familiar with React components and how to use props and state to control them. To start using React Intl we need to add it to our project: To localize an application we need to provide translations for messages throughout the application. We are going to store translations in separate files, one JSON file per locale. This way we can easily add new locales as needed. But it's up to you to select a way you want to store translations, React Intl does not require any specific approach for that. For example, here's how we store a welcome message translation for the English locale in the en.json file and French in fr.json : Both files define a translation for the welcome message. React Intl is using a special syntax for messages, that allows specifying placeholders in a text. We define the {name} placeholder here that we will fill with an actual value later. The IntlProvider component from React Intl provides the internationalization context for an application. We need to wrap our application with this context provider. This allows accessing internationalization information from any React component in the application. There are additional components that allow using the internationalization context. Let's display a welcome message with an ability to switch locales: In this example, we start by importing IntlProvider and FormattedMessage components. We also import translations for English and French locales from JSON files. As our welcome message contains the {name} placeholder, we define the values object with the name property that contains the name to use. React Intl will use this object to provide a context for a welcome message. Next, we wrap our application with the IntlProvider component. We specify the locale to use with the locale property and translations to use with the messages property. Finally, we're using the FormattedMessage component to properly format a message. We specify the id property for the component. We also provide the values object to the values property. The FormattedMessage will use its id to get the corresponding message from the IntlProvider messages (which is our welcome message). It will then use the values property to replace the {name} placeholder and display a formatted message. In addition to the IntlProvide context provider, React Intl provides a set of components that help to translate, format and pluralize information. The FormattedMessage component that we've seen is one of such components. There are additional components, like FormattedDate , FormattedNumber , and FormattedPlural , that can be used to format separate dates, numbers, and text messages. The syntax for messages used by React Intl allows specifying placeholders in a text along with their formatting rules. Let's add some more messages with placeholders: Here's how placeholders will be formatted: Let's display a message with a welcome text, numbers, and date. Note how numbers and date formatting differs for locales: We've specified values for the last visit date and a number of messages in the values object. Next, we've used FormattedMessage components to display translated messages. The id of each component corresponds to a particular message. React Intl is a library that helps to internationalize React applications. It provides components and API to format text, numbers, and dates. With the internationalization context provided by React Intl, we can use translation and formatting in any React component throughout the application.

Thumbnail Image of Tutorial Quick Introduction to Internationalization in React with react-intl

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Redux vs Context vs State

An in-depth look at State Management in ReactWithin the last year or so, the landscape for state storage in react has seen a tremendous shakeup. A new implementation of context has launched, which is much simpler and straight forward to use. We’ve seen React hooks released, and with things like functional states and useReducer, seemingly the option to replace redux. Not to be left behind, React-redux has joined the hooks train and given you a new way to perform state collection and dispatching with useSelector and useDispatch. But are these even needed anymore? Despite how vocal the community has been on us breaking away from redux, or state management libraries as a whole, the solution isn’t that simple. We need to break down some possible architectural decisions in our applications, and then investigate how these tools can both support or derail this architecture. Before we go any further, I think we should take a step back and ask a couple of simple questions about our choices: Answering these questions will hopefully give you a strong foundation going forward. So when you encounter an issue and need to choose the best tool available, you can make an informed decision to do so. As the saying goes: With that ado, let's jump in. Within the last year or two, there has been a shift in acceptable patterns of react state management. To talk about today, let’s take a little walk through a timeline of React state management to see why we’ve made the decisions we have today. Flux architecture is where I’m going to start, and for many people at the time, it was a strong selling point to migrate over from other frameworks. I remember starting a new job as the only front end developer on a new project. I had been programming away on it using Angular 1, my old go-to framework, for a couple of months when I saw my first video about flux. That week I stopped and rewrote the project to React. I had used React previously, and I think as a lot of people felt, never really cared for JSX, but seeing this flow, everything made sense. Soon afterward, Redux came out, and I hopped on the hype train as well. There’s quite a lot of ways to use Redux, and there’s no “true” accepted pattern. But let's examine it as I believe most people use it. Redux gave users a central store to store their entire state to, only accessible by the “flux” architecture style. And boy did they save their entire state. For the first year or two, it seemed to be the prevailing norm to store absolutely all state data in the store, regardless of what it was. To match this style of state management, applications were built entirely around the concept of “dumb components” and “smart components/containers.” Dumb components would have no access to any state and were only be visual components. You would have tons of these components, and your containers would collect the data you needed. Soon enough, stores turned into these unwieldy pieces of data that were impossible to follow and often required an in-depth knowledge base of the code to understand where everything was stored. Furthermore, this rule of “dumb/smart components” was perhaps overused, and a lot of codebases ended up in this state where you would only have a single container per page. So, to fill in that page data, you’d often need to prop drill the entire way through, creating an absolute mess to follow. We’re going to call this the Store-owns-all era . Soon after, there was a push for more code colocation and less dependency on absolutely all code in your store. Often, people moved to styles like domain/feature-based architecture, where a single spot in the store was representative of a feature. Dumb components still existed, but you would frequently extract those to some sort of global dumb components shared across the codebase or even an external repo, and you could share that UI framework. The store was cleaned up, and designated areas of the application were stored in the properties of the store. These areas may or may not line up to domains or pages. There was also a push to move UI state out of the store and into the components themselves. To combat prop drilling, there was a trend away from having only a single container at the top level for a page. Instead, a page would contain multiple containers, each housing its feature on the page. Also, the new context system (and later hooks as well) launched around this time. Interestingly, it didn’t seem like a ton of people moved to use context at the time to avoid prop drilling. This tendency seemed to align with hooks usage more. We’re going to call this phase the Features owns data era. The store still owned the data, and often they were related to a feature set as a whole. The components frequently don’t know how the data got there, or what happens with it, only that it owned that slice of the store. Which brings us to the era of today, where Components own data . This style is picking up more and more steam. This style can be handled by Redux but is more predominantly related to Apollo. The idea is generally that a component should own its own “lifecycle.” That includes knowing to get data, display loading when it’s not ready, knowing when it needs to recollect data, etc. There is still one or more stores, but it should be smart enough to know which data is related to one another. Do two different components need the same data? They can share it, but they both know how to collect that data as well. If one of the components collects new data, that will update the other as well. This style is complimented well by a lot of recent and upcoming initiatives by the react team, such as suspense, both for data fetching and for component initialization. It removes this idea of “did someone collect my data yet,” and instead, the component can confidently render itself. Component ownership also compliments the idea of concurrent mode too, which gives more control of the component's lifecycle to the component itself. If you have not tried out something like Apollo, I highly encourage it. It’s a bit challenging to move away from the more classic styles from before, but I find the system more durable, especially for larger teams. Someone doesn't need to know your components/containers, and the structure of your redux store, plus other dependencies, to understand how they can use it. Instead, they can trust your component will always handle itself. With that being said, this article is not going to be going into the Components own data phase. This is a relatively deep topic, and that talk can be saved for another day. I highly encourage anyone interested to check it out. I also want to demystify the differences between redux and context, and adding Apollo to the mix will add too much noise, without enough investigation. The questions we highlighted at the start of this article are still foundational to the first two phases (and can be used in the third), and I want to examine the them further. I think most small-to-medium size applications rely on the Store-owns-all and Features-own-data strategies, so we should understand what we’re doing, and what caveats to watch out for. With the philosophy out of the way, let's jump into the functions we'll cover more in-depth. The four primary ways I want to investigate are There are many more options out there, including the popular libraries Mobx and Apollo (as mentioned earlier). I’m going to stick to these, though, as most of them share enough similarities to redux that the knowledge is transferable. So what are each of these? Let start at the basic’s, component state. For the entirety of this blog, we will frequently be using the function state with hooks, but this information can be shared with class components as well. A components state is declared by using the useState hook, which stores data within the given component, and persists throughout renders. This state is not mutable, meaning if you try to set it, it will not update. To update that state, you must use the setState function returned while initializing. So what’s the difference between using a state variable and using a local variable. The state variable is intrinsically tied to the lifecycle of the component. While local variables will reinitalize each time the function is executed, the state will maintain. A pronounced difference between local variables and state is that changing any state will cause the function to execute again. Local variables, and the upcoming mutatable ref variables, will not trigger this rerender. Therefore, if you update a local variable with a new value, and that value should be output in the JSX, the change will not be visible. It's important to note that even after we change our state, the value of the state variable won't update until the next running of our function. That's’ because the component won’t immediately stop and rerun itself. This would cause a memory leak. Let's take a closer look at this in action: Try it yourself! Note that each time you click the button, the screen will show 1 number higher than what your console logs out. Why is this important? This should give you an idea of how the state works behind the scenes with the react component. It is directly tied to the lifecycle or current “state” of your React component. Although React state can be used for data storage, doing this in medium or larger applications can cause your code to be more unwieldy and harder to understand. Despite the complex name, each of these is the same thing. Or at least serve the same purpose. For a moment, let's look at a class component with an instance variable, as I believe they are easier to understand at a glance. Try it yourself! So in the above demo, we’ve created a variable for the class. It will reside with only that single instantiation of the class (hence the “instance” variable). If you click the Inc Instance button, it should become very apparent the difference with the state variables. It did not update visually. That’s because instance variables are not tied directly to the lifecycle of a component, and cannot cause the component to rerender. A components current visual state is a mixture of the current internal state and props of a given component That’s not to say other things can’t become a factor, and instance variables are an example of one of these factors. A good rule of thumb is to avoid these external factors as best as you can. The more external factors you add to a given component, the less predictable and pure your component becomes. This is a breeding ground for bugs and code that is challenging to reason about. Now, back to the example above, if you examine the logs while clicking the instance button, you’ll notice the correct number for where we should be at is displaying. So the data is storing correctly, and if we click the Inc State button, we actually will see that, given a rerender, that data is now correctly displaying. Now, there are some rare cases that this is useful. Let's come back around to these in our next section. As we said earlier, instance variables are not a thing in functional components. That’s because each time the component is rendered, those variables are reinitialized. Given that, there is a mechanism that allows this functionality, and those are useRef. Of course, useRef serves the purpose of attaching to a DOM element typically, but we can also use it for creating mutable values that can exist through renders. Check out the Hooks API Reference – React for more information. Here’s where things start to get interesting. Context is a mechanism designed to store data, and alert consumers when that data has changed. This kind of sounds like state, but isn’t quite the same. Context doesn’t have any rules around telling the Provider component itself when a change has occurred; rather, it’s mechanism is to instruct consumers when it notices the provider's value has changed. Using context can be confusing to read and understand at first. So let's jump into some examples. Try it yourself! The first example is a simple context, not using any state. We provide data to the context, which is used in our LevelOne component as a provider, and our LevelThree component as a consumer. The data is displayed there correctly and outlines a good use case of this style of context — some sort of static data that is passed throughout our components. But what if you want this data to be dynamic and change? Notice the button in our example is set up to change the context data object. But clicking the button changes the data, but doesn’t change our context on-page. Now, perhaps if you are used to React or Javascript, it seems pretty apparent that changing this data won’t change our context value. That code only runs on the initialization of the module. But if you start walking through the steps of how to include that within the component lifecycle, you will inevitably begin to use state. And that’s important. If you are to take a look at the Context object itself, you will see there are no public functions to update our values. That's because although the context object’s primary purpose is the mechanism to update consumers on the provider's value change, it does not provide tools to rerender the component that houses the provider. Instead, it is similar to a Pub/Sub pattern that informs its subscribers when the value has changed. We need a different tool to store the data and inform our component to rerender when that data changes. And React already provides us with that tool, state. Building on the foundation we covered earlier, to control the Provider's lifecycle, we need to tie in state. Let’s see an example of how to do that. Try it yourself! Notice that we are now storing the data in our LevelOne state. That data and its setter are placed into the Context provider's value. Now, when we click the button, this will cause the following events: If you’re new to Context, you may wonder why you would ever use this, as you could simply pass the values as props. That's a question we are going to come back later in this article, but let's look at one more example that displays the power of context. Try It Yourself! In this example, we’ve now memoized our components and added a console.log to print when that component is rerendered. If you try the case yourself, you’ll see each component executed precisely once. Now click the Change context button, you’ll see only Level One and Level three were called. So what does this mean? It demonstrates the Pub/Sub-like pattern that the Context system employs. Let’s draw a picture to walk through these events. Let's follow the chain of events in the above picture. A user has clicked on the button to update our context data. The context itself will notify all of its consumers if that data has changed. There’s no need for us to rerender Level two since none of that has changed. This is a rather trivial example, but you can imagine for deeply nested components, this can be rather handy. This is where the idea for “replacing redux” has come from, and we’ll return to this more in the future! To get a better idea of this system, we’ll start with a dive into some of the innards of Redux, and then how react-redux uses them. Redux is a state container for javascript applications. Although built initially for use with React, it is in no way tied to React. Instead, we use a library from the same team called React-Redux to connect Redux to React. The actual structure and shape of a redux store are entirely on the user. It must fit the same shape as the original passed in state, which they refer to as Preloaded State . Traditionally, this is an object and is placed into the variable currentState . At this point, nothing complex is happening, and we just have a single variable that stores our data. Now we want to turn this into a pub-sub. The PubSub pattern is a form of an observer pattern where users can “publish” updates to a central system, and any subscribers listening to those events are updated accordingly. So what do these steps look like in our system, let's look at the events in sequential order: So who are the listeners? In the case of Redux, it is any entity that has subscribed to it. You may have seen the syntax for it before, but it happens after you create the store. Middleware is built using this API, as well as react-redux. Again, not React specific, absolutely anything can tie into this pub-sub and know about state changes. One thing you might notice here is, absolutely every single change to the store will call our subscribed event. Does this happen under the hood of our react components? Wouldn’t that be heavy, as each component will be updated no matter the change? Well, that’s an excellent opportunity to dive into React-Redux. React-Redux is a binding library, used to connect react to redux. That’s not all it does though; it also gives us several enhancements under the hood that are often overlooked. Before we look at these enhancements, let’s see how it connects the redux pub-sub to our components. This can be done one of two ways, either with the traditional Connect syntax or with the newer useSelector and useDispatch hooks. First, let’s talk about their similarities. Both of these approaches use the React Context system to pass the store instance to any child components in the react tree. Note that this isn’t the store state itself; this is collected later. Beyond that, there are a couple of misconceptions about how context is used in React-Redux. We saw earlier that the Context system does have a mechanism to inform child components that our values have updated. But react-redux does not use this mechanism. Instead, they subscribe directly to the store itself and use the store pub-sub to be notified of possible state changes. This is the store.subscribe() that we had mentioned earlier. Code can be found here When the store state changes, it will call checkForUpdates, which determines if the state alteration has any effect on this component. If it does, it calls forceRender, rerendering this component. In this entire flow, the Context is never used. So then what’s the purpose of it? The purpose of Context within this system is to do exactly as we said above. We use the Context provider to tell React where this store is housed in the hierarchy of the React tree. Any child components of that provider have access to that store instance. This gives us the ability to have multiple stores, nested stores, and a cleaner approach to passing the store instance. Why doesn’t react-redux use Context to update the child components? There’s a Github Issue outlining the reasons this wasn’t used, but I want to look at a purpose that we’ve already described in this post. Remember the context example we used before . We were able to reduce the amount of rerenders in our system to two. They were LevelTwo (the component with nether provider nor consumer) was not rerendered because it was memoized and had no changed props that would need to update the component. That means, for any children of the provider, and any children of the consumers, your components should be memoized as to reduce unnecessary rerenders. Particularly children that do not require props from said state updates. Now, I’m not arguing memoization. Memoization is a crucial tool in your belt, that is under-utilized and often misunderstood (perhaps an article on that next). But that’s a pretty hefty requirement to your components and any future components. There’s also one other issue we come across that I left purposely vague in our list above. In our example above, we only have a single consumer, and therefore don’t see the full extent of what this means. Let’s build a case with two components with consumers instead. Try it yourself! So we’ve updated our context to have two consumers, and both of those components are being displayed at a sibling level in LevelTwo. Now, when you click either of the buttons to update one of their states, you should see: No matter what, both of these components are rerendered. Despite them both being memoized, and at a sibling level. That’s because context only notifies their consumers that a change has occurred. It does not know whether that change affects the component using that consumer. As our application grows, this problem also grows. There are strategies around this, which we will get more into later, but this is why react-redux does not use context to update their components. Instead, react-redux relies on its internal pub-sub to notify children. So how do the rerenders look when we use react-redux. Let’s start with a code example, and then walk through a diagram to explain the steps. Try it yourself! Here’s our code now using a redux store, connected through the react-redux provider and hooks. Note there are some additional boilerplate like the reducer and actions that aren’t present here. You can check out the code example above to see more. So what happens now when we click the Change context button? Our output should look like this: Each component was called once for the initial render. And now, when we update our Level Three component, it only rerenders that single component. Not even our provider component updates. And you’d see that if I expanded our into two LevelThree components like our last example, only a single one would update (assuming they were different state values). How is that? Well, partially yes, because of the Redux subscriptions. But you might recall from the redux breakdown above, a subscription gets called for every single change in the store. And that does happen here, but react-redux gives us more under-the-hood tools to help increase performance. Here are the steps it takes: This flow can be seen here : Note: That equality check is where connect and useSelector start to have some differences. We’ll dive into those in a moment. At a high level though, these work similar. An even more simplified version is broken down in this diagram: Note, any child of component three will also still be rerendered. So it’s still on the developer to ensure that child components are properly memoized if that’s not desirable. Although the general idea: of useSelector and mapStateToProps are the same, there are some key differences under the hood that can throw you for a loop if you are not ready. That being said, I think these differences (in my experience) have been greatly exaggerated for what they mean for us as a developer using either tool. To help break down the differences we first need to understand at a high level what the structure of each approach are. Once we know the difference in architecture, the difference in style should be more clear. So first, let's examine each signature. Above is the Hook style, by using the useSelector hook of react-redux. Now let’s take a look at the classic mapStateToProps. Try it yourself! So as we can see above, the Hook can tie directly into the data and pull out the data that is needed. On the other hand, our HOC requires us to create a mapStateToProps function, pass that into our HOC, along with the eventual component. That component will then receive all state data as props. The DOM output is the same, but there is a difference in the structure of our react document. It appears that our Hook component resembles precisely the elements as they appear in our code. The connect HOC component is a little bit more complicated. Now, we know connect is a HOC, and if you’ve previously used HOC’s, you should have some idea how this looks, but let's diagram it. So we now have this extra component that wraps our component. This component is responsible for collecting the state data and passing it to our component as a prop. Now, because our component is wrapped with this higher-level component, some extra optimizations are performed out-of-the-box, which aren’t available for hooks. Namely, we can render both the component creation as well as memoize our actual connect HOC . So what does that mean for people using or migrating to hooks? It means that places you previously had “free” memoization caused by the connect HOC you will now have to handle on your own. For most cases, that’s as simple as wrapping your component in a React.memo. There is also a difference now in how equality is compared. Previously, the connect used a shallow equality check to determine if changes had occurred, whereas useSelector uses a ( strict equality check . This may sound like a more significant change than you might expect, but you can see in the example above that it doesn’t affect as much as you might think. With proper memoization to avoid rerenders, you’re likely fine. If you need a more strict equality check, the second argument to useSelector does let you specify the equality check. So which solution should you use? As I said at the start, the obvious answer is going to be “it depends.” But what does it depend on? Well, the truth is, you should use all of them. The idea of using one is going to stunt your application more than help it. Let's look at each one quickly. This should still be used for your UI state. Unless your UI state is necessary to know globally, I highly encourage you to house that data here. For those that don’t know UI state, this is something like, is that popover open? If it doesn’t make sense placing the state in the component itself, it likely makes sense in the parent. Putting too much UI state in your store makes is confusing and hard to follow. Furthermore, it tells the other developers on your team that there are likely other things dependent on that state, making your code harder to use. That being said, if your application is small enough, react state is likely more than enough to handle your use case. There are new tools that can make this easier on you, like useReducer, but just be aware of our tests earlier. If you application begins to scale, redux (or other state management libraries) will help that code scale as well, and aid you on performance and debugging. This one is a handy tool that I don’t think is known enough. That’s not to say you should be going for it immediately, as a mutable state is pandora's box of bugs. But, if you have some sort of data that needs storing and is used central to that component, but you don’t want a rerender from it, it can be a trick that comes in handy. Oddly, one place I’ve come across is when using old libraries. Perhaps we need to remember that some library has been called and is open somewhere on the page (think an old popper popup). This is a great way to have access across renders, but not change the actual element itself. I've also seen it for data passing in through effects, where there can be renders from other values, but the passed value should not trigger a rerender. Again, be careful with these, but they are handy to have in your back pocket. And with that being said, never use it as actual state management. I think Sebastian Markbage (one of the react devs) said it best: That being said, I’ve seen several places say, “we are using redux, so we should never use context.” I don’t necessarily agree with this if you are using context correctly. I think context should be generally used for static data that is passed throughout the application, such as for theming, and it’s particularly good at that. It doesn’t pollute the store and is very simple to collect. If you are interested in seeing how you can use redux to do some of these, I did create a simple react auth tutorial using context . I don’t recommend using this for a production application, but it could be interesting to you. I think Redux is still incredibly useful. There are other great tools out there, and I’ve personally moved to use Apollo more and more, but I think Redux is always the first thing I grab when my application gets to a point where I feel state management is needed, or I’m not using graphQL. Redux is incredibly easy to read, and although the boilerplate can be annoying, as you use Apollo more, you will pine some days for being able to see “all the magic.” I’ve moved a couple applications away from redux, to using state + context, as I became curious if there would be noticeable gains. Again, there is a decent loss to boilerplate. This is more noticeable in smaller applications, where redux boilerplate can take up a larger portion of the codebase. Shortly after migrating some of these projects, I had other developers come onto the team and use the application. They were able to deduce how the system worked, but we noticed that there was a larger amount of renders than our systems would normally handle. We didn’t have a strong handle on how context’s pub-sub differed from Redux’s. That investigation eventually led to the learnings here. Furthermore, we had issues come up that we weren’t able to properly debug as we were used to. Thats because great tools like Redux and Apollo have amazing dev tools to help you. Once you are missing things like simple state inspection, time travel, and dispatches, it’s going to become more frustrating. Thats also not even accounting for middleware. There’s an entire suite of libraries at your disposal that can hook into your redux middleware, and you’ll find you miss those pretty quickly. We wanted to just hook into the actions happening in our application, but without redux, we had to tie it more directly to the component itself. My honest feeling is that, outside of a small application, the issues people have with Redux are likely related more to how they are using it, not the tool itself. Are you still using it where the store owns everything? Can you migrate to a more domain, feature-owns-data structure? Even more, can you attempt a component-owns-data structure? These are questions we need to ask ourselves. Again, as the saying goes, it’s the bad workman that always blames his tools. As I said above, my habit is to use a tool like Redux or Apollo for my data management, my React state handles local information, often UI state, and context handles static data, such as theming. I see no problem having these tools used together where each has their own strength. That's a vernacular thats thrown out there a lot when you start employing these different tools in tandem with one another. You should only have a single source of truth! But that's not what this phrase is about. The intention is that for a single piece of data, you should only have a single source it comes from, that is always the true "data". The saying is also true even for a single store. You should not have multiple area's of your redux store containing the same data, as you'll end up following out of sync somewhere, and making your codebase a lot harder to understand. For a simple example, think about a prop coming into a component. It's pretty discouraged to then tie that prop to your state, like so. Can it be done for good reason? Yes of course. But you've now created two sources of truth for this element, the state, and the prop. If you're putting that value into the react state, you're likely going to use that version. But what happens if the prop updates? Or when the state remounts. You can handle these edge cases, but it makes your code more bug prone, and tougher to reason about. On the other hand, in this example, we have two sources of truth. One is the internal state, and the other is a prop. That's totally fine, and likely something you do all the time. But if you look at each piece of data, they successfully only have a single source of truth. So I'm fine with multiple stores of data. I've even seen many successful uses of multiple redux stores, often used as a "per page" redux store. This sort of thing actually made debugging a lot easier per page, as you only had relevant info in your store. You of course want to balance this all with making sure your code is easy to understand, but don't avoid one of these tools just because you're trying follow a rule that is targeting a different problem. The short answer here is a small application. That’s still a choice you can make yourself, as redux is rather tiny, but it does complicate your code if you have a couple of simple pages with nothing more. Let’s try and understand more by going by application size. If you are listening to tutorials online, the answer here would appear to be context. There has been a pretty vocal chunk of the community pitching to move away from redux, and instead handle state through context. As we’ve talked about above, I would encourage you not to do this. In a small application, yes, this is possible to do, but as we saw with our tests, this can scale out of control pretty quickly. It can be enticing to move away from the redux boilerplate, but you’ll find sooner or later that the boilerplate is often handier to have. Also, although passing props can get a bad name now, don’t undervalue it. Passing props is the API to your component, and the more you can put to your API, the more reusable that component can be. That’s not to say you shouldn’t use other means, but rather, don’t try to force a square peg through a round hole. If you have an element with 1 or 2 levels of children, it’s still a sensible structure to pass those children. Also, if you genuinely are having troubles with deep prop drilling, none of the solutions above are likely the answer to the problem, but rather a workaround. It’s likely that you have too many components and need to introduce better composability to your code. I would highly encourage you to check out Material UI's codebase or check out this video by Micahel Jackson . I really can group these into two because the answer is evident here. Context should not be your solution here, and I would highly encourage you to use a state management system. I find in medium applications is where more significant architectural questions come into play. In my mind, at this point, you should either be examining a stronger “domain” driven style using Redux or begin to look at components owning data. You can do this with react, but Apollo would be the first place I nudge you to read about this style. They have fantastic docs and articles, so please check it out . This was a rather large article to end up where we started, but I hope by passing through them, you no longer think about these state management styles as different choices, but rather a plethora of tools. They each have benefits that can and should be used together. It’s your job as a developer to understand where each one is strong and weak. These tools should not be a “choose one and forget the rest”, but rather each a tool in your belt. Then, when someone tells you “x tool is bad”, you can try to help them understand in what circumstances that tool truly shines. You want to make not only a great feature but also write code that is both readable and understandable. Developers should be able to come to your code, and by seeing what you used, quickly determine how the system works as a whole. These will often be assumptions, but if someone can read your code at a glance and assume correctly how the system works, you’ve done a fantastic job! Thanks for reading today! Cheers!

Thumbnail Image of Tutorial Redux vs Context vs State

How to Add Month, Week, or Day Calendar in React with FullCalendar

A full-sized calendar is a great way to display events, simplify meetings scheduling, or organize access to shared resources. In this article we will see how to add a full-sized calendar to a React project with FullCalendar. We will see how to add the FullCalendar to a project, configure, localize and style it.FullCalendar is a popular JavaScript full-sized calendar. It provides a React component that makes it easy to use in React projects. Using the calendar component we can display events in a month, week, day, or a custom view. For this article, we assume that you're familiar with React components and how to use props and state to control them. Let's start by adding FullCalendar to our project: The core functionality for the FullCalendar is in the @fullcalendar/core package. You will always need to add it. All additional features are implemented as separate packages. We add @fullcalendar/react for a React calendar component and @fullcalendar/daygrid for a Month view. Now, we're ready to display a full-size calendar in our React application: We start by importing the FullCalendar React component. We also import the dayGridPlugin that provides a Month view for a calendar. Next, we import CSS files with standard calendar styles. Finally, we use FullReact component to display a list of events. We specify a month view as a plugin in the plugins property. The list of events is specified in the events property. The FullReact component provides a list of properties that allow configuring a calendar. You can change the header and footer, override rendering for calendar elements, process click and dragging events, configure different views, and provide a data source for events. You can check the API documentation on the official web site to learn about available configuration options. Let's display a calendar with month, week and day views: For this example, we've added the @fullcalendar/timegrid package to the project. This package implements week and day views. Next, we import the timeGridPlugin plugin that will provide week and day views. We also import @fullcalendar/timegrid/main.css CSS file that provides styles for views. After that, we configure FullCalendar to display events. We specify plugins to use with the plugins property. We'll be using a month view from the dayGridPlugin , and week and day views from the timeGridPlugin . We specify the header configuration with the header property. The header will contain next and previous buttons on the left, title in the center, and buttons to switch between month, week, and day view on the right. In this example, we provide events list as an array of objects. We can also use a JSON file and addEvent function. All the data sources got parsed into an Event object used by all FullCalendar functions. For an event, we can specify a title, start and end dates, whether it's a recurrent event or an all-day event. The FullReact component provides the locale property that we can use to specify the calendar's locale: In this example, we've specified a Spanish locale for the calendar using the locale property. When it comes to styling, there are two options available. First, you can use the Bootstrap theme for a calendar. Second, you can customize standard styles up to your requirements. The following example displays a calendar with a modified color for day numbers and day titles: In addition to standard CSS styles we import the custom.css file that overrides specific styles of the calendar: FullCalendar provides a flexible React component that displays a full-sized calendar. It supports month, week, day, and custom views. We can configure a calendar, localize it and apply custom styling.

Thumbnail Image of Tutorial How to Add Month, Week, or Day Calendar in React with FullCalendar