<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.6">Jekyll</generator><link href="https://tameemiftikhar.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://tameemiftikhar.com/" rel="alternate" type="text/html" /><updated>2021-09-20T00:31:01+00:00</updated><id>https://tameemiftikhar.com/feed.xml</id><title type="html">Tameem Iftikhar</title><subtitle>Builder, Tinkerer, Entrepreneur, Startup Enthusiast &amp; Traveller</subtitle><author><name>Tameem Iftikhar</name></author><entry><title type="html">DAG Factories — A better way to Airflow</title><link href="https://tameemiftikhar.com/blog/2021/06/04/dag-factories.html" rel="alternate" type="text/html" title="DAG Factories — A better way to Airflow" /><published>2021-06-04T01:44:03+00:00</published><updated>2021-06-04T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2021/06/04/dag-factories</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2021/06/04/dag-factories.html"></content><author><name>Tameem Iftikhar</name></author><category term="data science" /><category term="programming" /><category term="software engineering" /><category term="coding" /><category term="data engineering" /><summary type="html">Using dynamically generated DAGs for scaling airflow</summary></entry><entry><title type="html">Every time you comment code — you’ve already failed.</title><link href="https://tameemiftikhar.com/blog/2020/05/26/every-time-you-comment-code.html" rel="alternate" type="text/html" title="Every time you comment code — you’ve already failed." /><published>2020-05-26T01:44:03+00:00</published><updated>2020-05-26T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2020/05/26/every-time-you-comment-code</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2020/05/26/every-time-you-comment-code.html"></content><author><name>Tameem Iftikhar</name></author><category term="startup" /><category term="programming" /><category term="software engineering" /><category term="coding" /><category term="rubyonrails" /><category term="rails" /><category term="ruby" /><category term="scaling" /><summary type="html">Hold your pitchforks and hear me out first…</summary></entry><entry><title type="html">Three simple yet profound ideas for rapid personal growth</title><link href="https://tameemiftikhar.com/blog/2020/02/18/three-profound-ideas.html" rel="alternate" type="text/html" title="Three simple yet profound ideas for rapid personal growth" /><published>2020-02-18T01:44:03+00:00</published><updated>2020-02-18T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2020/02/18/three-profound-ideas</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2020/02/18/three-profound-ideas.html"></content><author><name>Tameem Iftikhar</name></author><category term="self-development" /><category term="hustle" /><category term="self-improvement" /><category term="rubyonrails" /><category term="rails" /><category term="ruby" /><category term="scaling" /><summary type="html">It just might be the inspiration you’re looking for</summary></entry><entry><title type="html">Slick Like Ruby, Fast Like C — Does Such a Language Exist?</title><link href="https://tameemiftikhar.com/blog/2020/02/18/slick-like-ruby-fast-like-c.html" rel="alternate" type="text/html" title="Slick Like Ruby, Fast Like C — Does Such a Language Exist?" /><published>2020-02-18T01:44:03+00:00</published><updated>2020-02-18T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2020/02/18/slick-like-ruby-fast-like-c</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2020/02/18/slick-like-ruby-fast-like-c.html"></content><author><name>Tameem Iftikhar</name></author><category term="startup" /><category term="programming" /><category term="coding" /><category term="rubyonrails" /><category term="rails" /><category term="ruby" /><category term="scaling" /><summary type="html">Yes, yes, it does</summary></entry><entry><title type="html">The Ultimate Guide to Blazing-Fast Performance in Rails</title><link href="https://tameemiftikhar.com/blog/2019/12/29/the-ultimate-guide-to-blazing-fast-performance-in-rails.html" rel="alternate" type="text/html" title="The Ultimate Guide to Blazing-Fast Performance in Rails" /><published>2019-12-29T01:44:03+00:00</published><updated>2019-12-29T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2019/12/29/the-ultimate-guide-to-blazing-fast-performance-in-rails</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2019/12/29/the-ultimate-guide-to-blazing-fast-performance-in-rails.html">&lt;p&gt;Ruby on Rails is a tremendous framework when you want development speed for your project or startup. It’s useful right out of the box and comes with a plethora of behind-the-scenes magic to make your life easier. However, it’s not considered the fastest framework out there in terms of performance. You will find examples of individuals and companies drifting away from Rails in favor of something else. Despite this, there are many companies out there who have succeeded in scaling Rails and found success — just take a look at Airbnb, Github, Gitlab &amp;amp; Shopify.&lt;/p&gt;

&lt;p&gt;So before you jump ship, you should consider keeping performance at the forefront of your mind when working with Rails, and you can succeed too. This article aims to list the most important tips &amp;amp; tricks I’ve learned over the years to make Rails run at blazing fast speeds and scale to millions of requests per minute.&lt;/p&gt;

&lt;h2 id=&quot;general-tips&quot;&gt;General Tips&lt;/h2&gt;

&lt;p&gt;First off, there are some general tips to implement in your Rails project to set yourself up for success.&lt;/p&gt;

&lt;h3 id=&quot;set-up-an-apm&quot;&gt;Set Up an APM&lt;/h3&gt;

&lt;p&gt;You can’t improve performance if you don’t measure it first, making it necessary to have the right metrics tracked and monitored. You should be tracking load times, request times, and database query timings amongst other things. Personally, I’ve found &lt;a href=&quot;https://newrelic.com/&quot;&gt;New Relic&lt;/a&gt; to be one of the best APM tools for Rails but it is a tad bit on the pricey side. A more affordable alternative is &lt;a href=&quot;https://www.skylight.io/&quot;&gt;SkyLight&lt;/a&gt;’s free trial.&lt;/p&gt;

&lt;h3 id=&quot;stay-current&quot;&gt;Stay Current&lt;/h3&gt;

&lt;p&gt;I know personally how horrifying updating the Rails version for your project can be if you left it stale for too long, and I sympathize with anyone who had to go through this ordeal. So do yourself a favor and try to keep in sync with the newer versions of Ruby and Rails. This will help you skip the pain of jumping multiple versions and ensures that you have all the newer performance enhancements.&lt;/p&gt;

&lt;h3 id=&quot;pareto-principle-the-8020-rule&quot;&gt;Pareto Principle (the 80/20 rule)&lt;/h3&gt;

&lt;p&gt;This is a well-known rule when it comes to developing software — The Pareto Principle. It’s also known as the ‘law of vital few’ and states that for most events, 80% of the effects are generated from 20% of causes. The idea behind this is to not waste time on micro-optimizations while you have bigger issues that need resolution. You won’t accomplish much by shaving off milliseconds in serialization if your database queries are extremely slow. So pick your battles carefully.&lt;/p&gt;

&lt;h3 id=&quot;keep-it-lean&quot;&gt;Keep it Lean&lt;/h3&gt;

&lt;p&gt;Rails is backed by an amazing community behind it and a library of gems that can easily help you accomplish complicated tasks. But it’s easy to get carried away adding gems to your project, causing bloat. Be careful while selecting what gems to add to your project and try keeping your dependencies lean.&lt;/p&gt;

&lt;h3 id=&quot;be-lazy--do-it-in-a-background-job&quot;&gt;Be Lazy — Do it in a Background Job&lt;/h3&gt;

&lt;p&gt;Whenever you need to do anything complicated or long-running, consider throwing it into a background worker — sending an email, push notifications, uploading pictures and the like. Minimizing work in the main thread will ensure a snappy response for users. The good thing for us is that Rails has multiple options to achieve this easily — &lt;a href=&quot;https://github.com/mperham/sidekiq&quot;&gt;Sidekiq&lt;/a&gt;, &lt;a href=&quot;https://github.com/resque/resque&quot;&gt;Rescue&lt;/a&gt; or &lt;a href=&quot;https://guides.rubyonrails.org/v4.2/active_job_basics.html&quot;&gt;ActiveJob&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;change-your-serializer&quot;&gt;Change Your Serializer&lt;/h3&gt;

&lt;p&gt;If you have an API in your project you are most likely using the ActiveModelSerializers gem for serializing your data. I would strongly suggest switching over to the &lt;a href=&quot;https://github.com/Netflix/fast_jsonapi&quot;&gt;fast_jsonapi&lt;/a&gt; by Netflix. This gem is a whopping 25 times faster than the default ActiveModelSerializers and I can personally vouch for that from experience.&lt;/p&gt;

&lt;h3 id=&quot;cache-me-outside&quot;&gt;Cache Me Outside&lt;/h3&gt;

&lt;p&gt;Sometimes if you have a lot of static data or you can’t make things faster, another alternative is to use a cache. Rails makes this incredibly easy to do right out of the box. Here is an example of how easy it is to do a cache with an expiry time:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;# Lets say you have some categories you offer in your project.&lt;/span&gt;

  &lt;span class=&quot;no&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;categories&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;expires_in: &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;minutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
      &lt;span class=&quot;no&quot;&gt;Categories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;active-record-database&quot;&gt;Active Record (Database)&lt;/h2&gt;

&lt;p&gt;ActiveRecord is the magical ORM (one of the best ever to exist) offered by Rails. It’s easy to get caught up in the ease of use without understanding the details which can lead you to bottlenecks in the future.&lt;/p&gt;

&lt;h3 id=&quot;use-thy-database&quot;&gt;&lt;strong&gt;Use Thy Database&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;This is something that goes unnoticed or unimplemented by a lot of developers as they rush to do everything in code or maybe they are intimidated by writing raw SQL. But whenever possible or convenient, you should use thy database. Processing and sorting data structures in Ruby can chew up CPU time, while your database can do this without breaking a sweat.&lt;/p&gt;

&lt;h3 id=&quot;peek-behind-the-curtain&quot;&gt;Peek Behind the Curtain&lt;/h3&gt;

&lt;p&gt;Don’t just get enamored by the magic of active record without worrying about what’s happening behind the scenes. In order for you to sweep out performance bottlenecks, you need to look at the actual queries that get triggered and understand them. In the development environment, Rails will print out all the queries getting run which allows you to notice any unnecessary queries. Also, here are a few tricks that will help you dig in a little deeper:&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/08579a3d2ac690fce395c21bedab4f11.js&quot;&gt; &lt;/script&gt;

&lt;h3 id=&quot;sql-wizardry&quot;&gt;SQL Wizardry&lt;/h3&gt;

&lt;p&gt;Don’t worry, I am not about to suggest you write everything in raw SQL queries. But learning the basics of SQL and database design will help you better understand what’s happening under the covers and allow you to optimize the queries as needed. It’s a valuable skill to have as a software developer and will go a long way in your career.&lt;/p&gt;

&lt;h3 id=&quot;be-stingy&quot;&gt;Be Stingy&lt;/h3&gt;

&lt;p&gt;One way to make your queries more efficient is to only select what you really need. Instead of doing a SELECT * specify which columns you need the database to retrieve. By default ActiveRecord selects everything but you can leverage select or pluck to fix this problem.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/d219ccc9745d4bd11a7f7da9f8d743f6.js&quot;&gt; &lt;/script&gt;

&lt;h3 id=&quot;n1-queries&quot;&gt;N+1 Queries&lt;/h3&gt;

&lt;p&gt;This is a classic problem. If you are loading a Blog from the database and then try to find all the comments for that blog by looping through the records, you are forcing Rails to run a query for each of the comments. This can be eliminated by preloading the comments Blog.includes(:comments) and helps avoid the N+1 query problem. &lt;strong&gt;Pro Tip:&lt;/strong&gt; take a look at &lt;a href=&quot;https://github.com/flyerhzm/bullet&quot;&gt;Bullet&lt;/a&gt; gem to help you find any N+1 query problems.&lt;/p&gt;

&lt;h3 id=&quot;combining-queries&quot;&gt;Combining Queries&lt;/h3&gt;

&lt;p&gt;When working with bigger teams with multiple developers on a project, sometimes you will notice every person touching the codebase might be adding queries throughout the code path. More often than not, these queries can be combined into fewer queries at the top of the code path. This ensures there are no duplicated queries and allows the database to strategically do the heavy lifting.&lt;/p&gt;

&lt;h3 id=&quot;index-index-index&quot;&gt;Index, Index, Index&lt;/h3&gt;

&lt;p&gt;This is a database best practice that shouldn’t be ignored. If you don’t index properly you will negatively affect database performance and cause unnecessary table scans. When building a new feature think ahead to what will be queried in the project and attempt to add the correct indexes. If you have an existing project you can always use &lt;a href=&quot;https://github.com/gregnavis/active_record_doctor&quot;&gt;Active Record Doctor&lt;/a&gt; or &lt;a href=&quot;https://github.com/plentz/lol_dba&quot;&gt;LolDBA&lt;/a&gt; to sniff out missing indexes.&lt;/p&gt;

&lt;h3 id=&quot;migrations&quot;&gt;Migrations&lt;/h3&gt;

&lt;p&gt;When you are running at scale, and you have millions of records in your tables the normal way of running migrations in Rails will, unfortunately, fail you. They will either error out or lock tables for extended periods of time, taking your site down. Having dealt with this in the past there are two tools that will solve this pain point for you:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/github/gh-ost&quot;&gt;Gh-ost&lt;/a&gt;: This is a triggerless online schema migration solution for MySQL and the only tool that worked for me at scale.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/soundcloud/lhm&quot;&gt;LHM&lt;/a&gt;: This will migrate your tables while they are still online without locking your table.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;extreme-tip-use-raw-sql-if-you-dare&quot;&gt;Extreme Tip: Use Raw SQL if you dare&lt;/h3&gt;

&lt;p&gt;If there is an endpoint where you desperately need performance, you can consider combining all the Active Record queries throughout your functionality to a single massive SQL query at the top to pull out any records you need to fulfill the use case. &lt;strong&gt;Disclaimer:&lt;/strong&gt; Yes, it’s hard to maintain a massive raw SQL query, and it’s also less readable. But I did mention this is only in case of desperation.&lt;/p&gt;

&lt;h2 id=&quot;servers--hardware&quot;&gt;Servers &amp;amp; Hardware&lt;/h2&gt;

&lt;p&gt;When deploying a Rails project there are a few things to remember regarding the underlying infrastructure and architecture.&lt;/p&gt;

&lt;h3 id=&quot;choose-a-scalable-architecture&quot;&gt;Choose a Scalable Architecture&lt;/h3&gt;

&lt;p&gt;With cloud infrastructure having come such a long way, gone are the days of having to build bare metal servers in order to scale your application. When deciding on your underlying architecture for a Rails project you should utilize a scalable cloud-based system. As an example, you can use AWS Fargate or Kubernetes to automatically scale your dockerized Rails application as needed.&lt;/p&gt;

&lt;h3 id=&quot;brotli-compression&quot;&gt;Brotli Compression&lt;/h3&gt;

&lt;p&gt;Brotli is another compression algorithm based on gzip with multiple improvements and a better compression ratio. It is now supported with most web servers and adding it is an easy way to optimize the compression speed. And well, who doesn’t want free web performance improvement. (Reference: &lt;a href=&quot;http://www.instantshift.com/2018/03/02/gzip-vs-brotli-compression/&quot;&gt;Brotli vs Gzip&lt;/a&gt;)&lt;/p&gt;

&lt;h3 id=&quot;give-it-more-juice&quot;&gt;Give it More Juice&lt;/h3&gt;

&lt;p&gt;Rails is notorious for using a lot of memory, especially if you have multiple puma workers running. So don’t let your application go thirsty, and give it some juice from the start. You can utilize memory-optimized instances on your cloud provider to set you up for success. And don’t forget to keep an eye on the swap usage on the server.&lt;/p&gt;

&lt;h3 id=&quot;tuning&quot;&gt;Tuning&lt;/h3&gt;

&lt;p&gt;Since Rails 5 the webserver for Rails has been switched to Puma, and by default, it will only run one worker. As soon as you set up your Rails deployment make sure to increase the number of workers to the available cores on your machine or something more reasonable.&lt;/p&gt;

&lt;h3 id=&quot;http2&quot;&gt;HTTP/2&lt;/h3&gt;

&lt;p&gt;If you are utilizing a reverse proxy like Nginx make sure you have the HTTP/2 option turned on to give you all the performance advantages you get from it.&lt;/p&gt;

&lt;h2 id=&quot;the-cherry-on-top-miscellaneous&quot;&gt;The Cherry on Top (Miscellaneous)&lt;/h2&gt;

&lt;p&gt;We are almost at the finish line — this section is all about some extra tips for performance.&lt;/p&gt;

&lt;h3 id=&quot;dont-use-dynamic-methods&quot;&gt;Don’t Use Dynamic Methods&lt;/h3&gt;

&lt;p&gt;Rails magic comes with a price. A few of these methods consume a lot of resources and it would be better to skip using them. As an example, the find_by() and find_all_by() are kind of slow because they need to run through method_missing and parse the name against the list of columns in the DB.&lt;/p&gt;

&lt;h3 id=&quot;throttling&quot;&gt;Throttling&lt;/h3&gt;

&lt;p&gt;As you scale you are bound to run into malicious attempts on various endpoints that can’t be cached and will cause expensive operations to chew up resources. To get around this, I would recommend adding a gem like &lt;a href=&quot;https://github.com/kickstarter/rack-attack&quot;&gt;rack-attack&lt;/a&gt; to implement throttling on endpoints like login, reset password or sign up.&lt;/p&gt;

&lt;h3 id=&quot;know-your-on-vs-o1&quot;&gt;Know your O(n) vs O(1)&lt;/h3&gt;

&lt;p&gt;As the data set size increases we need to heed the impact of our code in terms of time complexity. In a scenario where lots of data needs to be processed or looped over, consider using a hash instead of defaulting to arrays.&lt;/p&gt;

&lt;h3 id=&quot;always-use-a-cdn&quot;&gt;Always use a CDN&lt;/h3&gt;

&lt;p&gt;All your static assets should always be fronted by a CDN and make sure the cache policies are reasonable. If you want granular control over the cache invalidation, you can look into using e-tags and Cache-Control.&lt;/p&gt;

&lt;h2 id=&quot;advanced&quot;&gt;Advanced&lt;/h2&gt;

&lt;p&gt;In extreme cases, you can consider some advanced optimizations. I would argue if you’ve reached this point it might be time to consider other languages for certain parts of your project that are computationally intensive, so I will keep this section brief.&lt;/p&gt;

&lt;h3 id=&quot;brush-up-on-c&quot;&gt;Brush up on C&lt;/h3&gt;

&lt;p&gt;The main implementation of Ruby is written in C, which allows you to rewrite the slow part of your code in C as an alternative — e.g. if you are doing crypto algorithms for generating certificates. If you aren’t so excited about the idea of dwelling into C code, you can leverage third-party gems written in C bythe Rails community.&lt;/p&gt;

&lt;h3 id=&quot;faster-background-jobs&quot;&gt;Faster Background Jobs&lt;/h3&gt;

&lt;p&gt;With an increasing background workload, you can switch your background workers to a more performant language. By utilizing queues like Redis or Amazon SQS, the workers can be decoupled into their own microservice. Checkout this Sidekiq compatible &lt;a href=&quot;https://github.com/jrallison/go-workers&quot;&gt;go-workers&lt;/a&gt; library or a version of sidekick written with &lt;a href=&quot;https://github.com/mperham/sidekiq.cr&quot;&gt;Crystal&lt;/a&gt; as two options.&lt;/p&gt;

&lt;h3 id=&quot;try-faster-versions-of-ruby&quot;&gt;Try Faster Versions of Ruby&lt;/h3&gt;

&lt;p&gt;There are a few implementations of Ruby aiming to increase the performance. If you are interested in these variations, take a quick look at &lt;a href=&quot;https://github.com/oracle/truffleruby&quot;&gt;Truffle-Ruby&lt;/a&gt; or &lt;a href=&quot;https://www.jruby.org/&quot;&gt;JRub&lt;/a&gt;y.&lt;/p&gt;

&lt;h2 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h2&gt;

&lt;p&gt;If we look at companies using Rails we see that they were able to utilize the amazing development speed of Rails to put their customers first, and also managed to improve performance as they scaled. In this article, we talked about multiple tips &amp;amp; tricks for increasing performance. I hope you found this guide helpful. Till next time.&lt;/p&gt;

&lt;h2 id=&quot;love-talking-tech-or-startups&quot;&gt;Love talking tech or startups?&lt;/h2&gt;

&lt;p&gt;You’re in luck, me too! If you want to chat about cutting-edge technology, entrepreneurship or the perils of being a startup founder, find me on &lt;a href=&quot;https://twitter.com/TameemIftikhar&quot;&gt;Twitter&lt;/a&gt; or on &lt;a href=&quot;https://www.linkedin.com/in/tameemiftikhar/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;</content><author><name>Tameem Iftikhar</name></author><category term="startup" /><category term="programming" /><category term="coding" /><category term="rubyonrails" /><category term="rails" /><category term="ruby" /><summary type="html">Ruby on Rails is a tremendous framework when you want development speed for your project or startup. It’s useful right out of the box and comes with a plethora of behind-the-scenes magic to make your life easier. However, it’s not considered the fastest framework out there in terms of performance. You will find examples of individuals and companies drifting away from Rails in favor of something else. Despite this, there are many companies out there who have succeeded in scaling Rails and found success — just take a look at Airbnb, Github, Gitlab &amp;amp; Shopify.</summary></entry><entry><title type="html">Bougie to startup founder — Tips for living on a budget.</title><link href="https://tameemiftikhar.com/blog/2019/12/16/bougie-to-startup-founder.html" rel="alternate" type="text/html" title="Bougie to startup founder — Tips for living on a budget." /><published>2019-12-16T01:44:03+00:00</published><updated>2019-12-16T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2019/12/16/bougie-to-startup-founder</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2019/12/16/bougie-to-startup-founder.html">&lt;p&gt;So you’ve finally decided to quit your cushy job to pursue your own startup dreams. Good for you champ! I know personally how daunting it can be and requires some habit and lifestyle changes. You might be living off your own means while you wait to raise a round of funding and build your first product. Now it’s time to cut some Uber bills, delete a few delivery apps and break up with toxic subscription providers — the things we do for our dreams . . . I’ve personally been through this process and have compiled some tips to get you on your way to becoming a personal finance wizard(ess)!&lt;/p&gt;

&lt;h2 id=&quot;budgets-budgets-budgets&quot;&gt;Budgets, Budgets, Budgets&lt;/h2&gt;

&lt;p&gt;Some of us have been through this before — downloading various budgeting apps with a newfound enthusiasm for personal finance, yet we eventually never follow through. I agree that budgeting is time-consuming and boring but unfortunately, it’s in your best interest to stick with it. Here are a few tips to make the transition easier:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Tracking budgets manually is difficult so automate this process by finding an app that works for you. (I personally use &lt;a href=&quot;https://www.mint.com/&quot;&gt;Mint&lt;/a&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Start by creating bigger buckets of budget categories — rent, bills, food &amp;amp; others. Take a few iterations to hone in on the right amount of the budget for each category.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once you’ve got the hang of those budgets, you can start to create more granular budgets in terms of drinks, groceries, clothing e.t.c.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important thing to remember while you take up budgeting is to think of it as an iterative process. Just like any habit, it will take time to establish it. You might set budgets and not meet them — but the key is to keep readjusting both the budgets and your spending habits until you find the sweet spot.&lt;/p&gt;

&lt;h2 id=&quot;detective-mode-activate&quot;&gt;Detective Mode Activate&lt;/h2&gt;

&lt;p&gt;When you are getting into this new habit, it is beneficial to sit down and sift through your bank statements with a detective’s eye. While doing this exercise the idea is to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Get intimately familiar with your monthly spending and habits.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Look for any unnoticed or unnecessary subscriptions or charges.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Banking fees that you might be paying for your account (there are options to get accounts that have no monthly fees).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;To come to terms with your bad spending habits and accept them as they stand now.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;reduce-your-monthly-bills&quot;&gt;Reduce your monthly bills&lt;/h2&gt;

&lt;p&gt;We keep paying for internet and mobile providers every year without wondering if there is a better deal out there. If you’ve been with your provider for a few years, it’s time to get some loyalty discounts or possibly find another provider. Seriously, it works. I saved a good chunk of change by calling both my internet and mobile providers and asking them for better plans.&lt;/p&gt;

&lt;h2 id=&quot;subscription-intervention&quot;&gt;Subscription Intervention&lt;/h2&gt;

&lt;p&gt;I know how much you love your subscriptions but let’s be honest- do you really need all of them? Maybe it’s time to break up. Start by going through your list of subscriptions and figure out what doesn’t spark joy. Some good strategies for better handling your subscriptions is to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Keep only one subscription service in each category that is important to you — music, video, fitness, e.t.c.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Set a limit for the amount of money you want to spend on subscriptions in total and cut them until you reach the goal.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Cut all of them, and slowly bring them back online if you can’t live without it. This one is a more aggressive strategy.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dont-skip-the-dishes&quot;&gt;Don’t “Skip the Dishes”&lt;/h2&gt;

&lt;p&gt;If you haven’t already, another lifestyle change that can save you money while also contributing to healthy habits is to start meal prepping. Keep in mind that when beginning this habit it can take some learning and getting used to. So you can try two different strategies.&lt;/p&gt;

&lt;h3 id=&quot;use-a-meal-service&quot;&gt;&lt;strong&gt;Use a meal service&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;If you don’t have the cooking skills or the time to spend on meal prep a good option might be to consider ready to cook meal boxes like Chefs Plate, GoodFood, or any of the others on the market. They are a good way to level up your cooking skills while enjoying delicious meals at home.&lt;/p&gt;

&lt;h3 id=&quot;learn-to-meal-prep&quot;&gt;Learn to meal prep&lt;/h3&gt;

&lt;p&gt;The other strategy is to get your hands dirty and learn how to meal prep properly. To get you started off on the right foot:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Decide on meals and recipes that align with your health goals and are easy to prepare and store.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pick ingredients that can be used in multiple recipes that have a longer shelf life.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pick a day for preparing the majority of the meals.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Bring variety to simple foods like baked chicken by having a good repertoire of spices.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;pay-off-credit-card&quot;&gt;Pay off credit card&lt;/h2&gt;

&lt;p&gt;Interest on most credit cards is through the roof so before you quit your job, make sure you pay off all your credit card debt. Ideally, you should never have debt on your credit card, but life happens and sometimes you have no choice. In the future, try and stick to buying things you can pay for in cash at the moment instead of depending on your credit card.&lt;/p&gt;

&lt;h2 id=&quot;the-bottom-line&quot;&gt;The Bottom Line&lt;/h2&gt;

&lt;p&gt;It won’t always be easy, but you’ve already taken the first step by looking into articles like this one. Stay vigilant and dedicated and it will become more natural with time. And yes, you can reward yourself once in a while with a night out, just don’t go wild. You’re not a millionaire. . . yet.&lt;/p&gt;

&lt;h3 id=&quot;love-talking-tech-or-startups&quot;&gt;&lt;strong&gt;Love talking tech or startups?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;You’re in luck, me too! If you want to chat about cutting-edge technology, entrepreneurship or the perils of being a startup founder, find me on &lt;a href=&quot;https://twitter.com/TameemIftikhar&quot;&gt;Twitter&lt;/a&gt; or on &lt;a href=&quot;https://www.linkedin.com/in/tameemiftikhar/&quot;&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;</content><author><name>Tameem Iftikhar</name></author><category term="startup" /><category term="entrepreneurship" /><category term="startupgrind" /><category term="startuplife" /><summary type="html">So you’ve finally decided to quit your cushy job to pursue your own startup dreams. Good for you champ! I know personally how daunting it can be and requires some habit and lifestyle changes. You might be living off your own means while you wait to raise a round of funding and build your first product. Now it’s time to cut some Uber bills, delete a few delivery apps and break up with toxic subscription providers — the things we do for our dreams . . . I’ve personally been through this process and have compiled some tips to get you on your way to becoming a personal finance wizard(ess)!</summary></entry><entry><title type="html">Authentication with React Context</title><link href="https://tameemiftikhar.com/blog/2019/11/11/authentication-with-react-context.html" rel="alternate" type="text/html" title="Authentication with React Context" /><published>2019-11-11T01:44:03+00:00</published><updated>2019-11-11T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2019/11/11/authentication-with-react-context</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2019/11/11/authentication-with-react-context.html">&lt;p&gt;Most react apps require the concept of authentication and storing user information. In these scenarios, you might end up with various components in the app that all need access to the same user information like the avatar or display name. On top of this, a few of our components might want to update this information and make it be instantly available everywhere else.&lt;/p&gt;

&lt;p&gt;Some go-to solutions for this use case could be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Add a package like redux to your project and add bloat for a simple use case.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Pass the information using props all the way down the tree, and create “props hell” for yourself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Use the observer pattern by using something like PubSub JS.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As of new React versions, there is a better way to accomplish this by using React Context (&lt;a href=&quot;https://reactjs.org/docs/context.html&quot;&gt;https://reactjs.org/docs/context.html&lt;/a&gt;). In this post, we will run through an example of how React Context can be used for this specific case. So let’s get right into it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/2000/0*9YQfPzafN5Yg5zK4&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Consider the following sample piece of code. We have a dashboard app that has two components somewhere in our tree: NavBar and UserSettings. Both these components need the user object and we can pass it through the props. This snippet is the extremely basic use case, but imagine having components nested deep in the tree and the pain of passing the prop all the way down.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/18e91a7a8d3428c6545a869efe393aa6.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;This example and more complicated versions of it can be handled well by utilizing react context to store the user information, and all the components within the app can then use it on a need-to-use basis. It’s time to run through a step by step example.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-user-context-component&quot;&gt;Setting up a User Context component&lt;/h2&gt;

&lt;p&gt;First of all, we will setup the react context. To keep our code clean, we will define a provider and consumer in the same component file. Create a new folder for context and create a new file &lt;code class=&quot;highlighter-rouge&quot;&gt;/src/context/UserContext.jsx&lt;/code&gt;.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/cf02fbfca93c71777db3c915e06e7641.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Code Break Down&lt;/strong&gt; 🕺&lt;/p&gt;

&lt;p&gt;In the code above we define a new user context by using the createContext helper and specify that it will contain a user object and a updateUser method that will be used to update the user data.&lt;/p&gt;

&lt;p&gt;We then define a UserProvider class that wraps any children in the context provider and keeps the required object in the state.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;// This provider will wrap the rest of the tree and we pass in the // user in the state and the updateUser function as well. &lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UserContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Provider&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/UserContext.Provider&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the end of the file, we also export the Consumer in the same file.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UserConsumer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UserContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that we have a UserProvider component we can run through a practical example of how it can be used in our application. To add a little complexity to our pretend example let’s assume the TopNavBar and UserSettings components are deeper in the tree and not in the App component.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-the-initial-value-of-a-user-in-the-context&quot;&gt;Setting up the initial value of a user in the context&lt;/h2&gt;

&lt;p&gt;We need to set up the initial value of the logged-in user in our main App.jsx component. This way as soon as a user logs in, the context is filled with the required user data.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/4965431340830ad80eb99ded244b9938.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Code Break Down&lt;/strong&gt; 🕺&lt;/p&gt;

&lt;p&gt;In the above code, our app component makes sure it pulls the logged in user’s information from the server and stores it in the state. Then the rest of our code gets wrapped in the UserProvider that we created earlier. Note that we are passing the UserProvider with the user prop to set up the value of the user in the context.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UserProvider&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;use-the-context-in-any-component&quot;&gt;Use the context in any component&lt;/h2&gt;

&lt;p&gt;Now that our app component wraps everything in the UserProvider component and setups up the initial value of our user, we can go ahead and use this in our components. Let’s circle back to the TopNavBar component and implement this.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;400: Invalid request&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/af8164af0e339a3d2fb8ba4a2d81b058.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;strong&gt;Code Break Down&lt;/strong&gt; 🕺&lt;/p&gt;

&lt;p&gt;Alright, we are almost at the finish line. In this component, you can see that we are loading the UserConsumer from our component we created earlier.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UserConsumer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;‘&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UserContext&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;’&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT NOTE:&lt;/strong&gt; In order to use the context in our component we need to wrap our component in the UserConsumer. I like to pass in the context as a prop to be used in the component. That’s what this next code snippet right here does. We wrap the component in the UserConsumer and pass the state to our TopNavBar component.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;withContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
       &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UserConsumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; 
         &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TopNavBar&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&amp;gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt; 
&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/UserConsumer&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;withContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Within the TopNavBar component, we have direct access to all the user info. We read it in our constructor and set it in the state to be read again.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;// Get the user from our context&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;updating-new-user-info-in-the-context&quot;&gt;Updating new user info in the context&lt;/h2&gt;

&lt;p&gt;Now you might ask, what about updating the user information when the user uploads a new picture? Don’t worry about it, I got you. Taking the TopNavBar component again we can access the function passed into the context. Just like we got the user info we can access the update function from context and call it to update the info.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;c1&quot;&gt;// Get the user from our context &lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updateuser&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;updateUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;newUserInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;In this post, we took a look at how React Context can be used to store global information that needs to be accessible by multiple components. It helps us write cleaner code without props flowing in all possible directions.&lt;/p&gt;

&lt;p&gt;I hope this was helpful, and if you have any comments feel free to reach out.&lt;/p&gt;</content><author><name>Tameem Iftikhar</name></author><category term="tech" /><category term="blog" /><category term="react" /><category term="javascript" /><summary type="html">Most react apps require the concept of authentication and storing user information. In these scenarios, you might end up with various components in the app that all need access to the same user information like the avatar or display name. On top of this, a few of our components might want to update this information and make it be instantly available everywhere else.</summary></entry><entry><title type="html">Introduction</title><link href="https://tameemiftikhar.com/blog/2019/08/10/introduction.html" rel="alternate" type="text/html" title="Introduction" /><published>2019-08-10T01:44:03+00:00</published><updated>2019-08-10T01:44:03+00:00</updated><id>https://tameemiftikhar.com/blog/2019/08/10/introduction</id><content type="html" xml:base="https://tameemiftikhar.com/blog/2019/08/10/introduction.html">&lt;p&gt;Hi everyone! I finally did it, I went ahead and took the time to setup a website and a blog. In true techincal nerd fashion, I had to set it up in Jekyll and deploy it with an automated pipeline that has deploy previews and split testing. Overkill? Maybe so. But hey, that’s the benefit of being a techie after all.&lt;/p&gt;

&lt;p&gt;So what am I gonna write about? Well, that part is still undecided and will come to me as the ramblings show up in my head. In the upcoming months you can hope to find tutorials, lessons I learned as a yong entrepreneur and other thoughts.&lt;/p&gt;</content><author><name>Tameem Iftikhar</name></author><category term="tech" /><category term="blog" /><summary type="html">Hi everyone! I finally did it, I went ahead and took the time to setup a website and a blog. In true techincal nerd fashion, I had to set it up in Jekyll and deploy it with an automated pipeline that has deploy previews and split testing. Overkill? Maybe so. But hey, that’s the benefit of being a techie after all.</summary></entry></feed>