<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Francisldn</title>
    <description>The latest articles on DEV Community by Francisldn (@francisldn).</description>
    <link>https://dev.to/francisldn</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F801206%2F8e7ad3e2-c2ae-43d5-a5a3-526cc21ed77f.jpeg</url>
      <title>DEV Community: Francisldn</title>
      <link>https://dev.to/francisldn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/francisldn"/>
    <language>en</language>
    <item>
      <title>Be Grateful for Rejections - Anecdotes about Rejections in Job Hunting Process</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Mon, 26 Dec 2022 16:41:19 +0000</pubDate>
      <link>https://dev.to/francisldn/be-grateful-for-rejection-2neg</link>
      <guid>https://dev.to/francisldn/be-grateful-for-rejection-2neg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Remember to constantly remind yourself: &lt;br&gt;
"Be grateful for the rejection, you are one step closer to getting a better offer!"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the completion of the Codeworks bootcamp, one then realises that an even bigger challenge is on the horizon. Yes, job hunting in tech is a daunting task, a full time job in itself. In particular, for someone without a meaningful commercial software development experience, one will likely face multiple rejections before one eventually lands on a full time software developer role. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Facing Multiple Rejections&lt;/strong&gt;&lt;br&gt;
In this article, having had the experience of facing multiple rejections, I would like to share some anecdotes about my experience with rejections and how I handled them with a positive mindset during the job hunting process. I hope that it will inject some positive thinking and provide some form of encouragement to others who are currently in the job hunting process, and hopefully will also inspire others to share your own experiences as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handle Rejections with a Positive Mindset&lt;/strong&gt;&lt;br&gt;
Receiving a rejection email or news from a company, which you have invested time going through various stages of the application process, can be demoralising. But it doesn't have to be that way. One can, and should, view job interview as a match-making process. You learn more about the company's culture, their way of working and the individuals that you will be working with, through the interview process, and you may or may not like what you have learnt. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoided a "Toxic Startup"&lt;/strong&gt;&lt;br&gt;
One of the first companies which I had interviewed with, had less than stellar reviews on Glassdoor. Inevitably, there will always be disgruntled staff in every workplace, but Glassdoor reviews give you a good insight about the company's culture and how the company treats its staff. In addition to the single negative review below, there were a few other similarly negative reviews about the company on Glassdoor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd08ezxowzdes8bwe9s54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd08ezxowzdes8bwe9s54.png" alt="Image description" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having gone through the 1st round interview with the company, I was invited to a live coding test, and I received a rejection email from the company after that. While it was disappointing, I was relieved at the same time. Had they offered me the role and had I accepted it, I would probably have walked into a "toxic workplace", to quote one of the former employee's reviews at Glassdoor. Sticking to a positive mindset, one can't help but feel lucky to have avoided this company. &lt;br&gt;
&lt;strong&gt;&lt;em&gt;Moral of the story: Rejection from a company is positive if the company has a toxic workplace.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoided a Shaky Startup&lt;/strong&gt;&lt;br&gt;
Early on in my job hunting process (around early October), I was invited to an interview for a frontend developer role with a crypto-bank startup. I spoke to the HR person in my 1st screening round and he assured me that, while the company was an early stage startup, they had a "solid, blue-chip" financial backer. And guess who was the financial backer? It turned out to be none other than the now-bankrupt FTX! Having passed the 1st screening round, I was given a technical take-home assignment, then I was invited to another live coding round with the Frontend Lead. I got a rejection email from the company after that. As we all know by now, FTX saw an implosion and collapsed in early November and, as they said, the rest is history.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Moral of the story: A rejection is a blessing in disguise when you found out, ex-post, that you have avoided a company saddled with funding problem due to the financial calamity of its financial backer.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Promised to be Agile But...&lt;/strong&gt;&lt;br&gt;
Another company which I had interviewed with, was truly fast-moving with their hiring process, at least initially. I completed the 1st screening round with the tech lead, 2nd round with the company's director/founder and 3rd round live-coding test, all within a week. When I met the company's director, he impressed upon me that, given the small size of the firm (about 20+ employees), the company adopted an agile hiring process and can move quickly with the right candidate without having to wait for other processes. &lt;/p&gt;

&lt;p&gt;Having gone through all the rounds, which I thought I had performed well and was given such impression during the process, I was promised to be informed of the outcome 2 days later. One week went by and no news from them, then came the second week, still no news from them for the first few days. Finally, on the final day of the 2nd week, I received a rejection news from the company. At this point, I had already received a great offer from another company, so I was not that bothered about this promised-agile-but-slow-moving company anymore. In a way, I was thankful that they had moved slowly, had they moved fast and offered me the role and had I accepted it, I would have missed a better offer from another firm (which is fully remote with great pay and benefits). &lt;br&gt;
&lt;strong&gt;&lt;em&gt;Moral of the story: Don't be disheartened if you received a rejection, be hopeful that there is a better opportunity awaits you around the corner.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Closing Thought&lt;/strong&gt;&lt;br&gt;
Facing multiple rejections is an inevitable part of the job hunting process, especially tech jobs. I hope that the anecdotes above would inspire you to embrace rejections with a positive mindset and strengthen your resolve to persevere and break into tech in 2023.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remember to constantly remind yourself: 
Be grateful for the rejection, 
you are one step closer to getting a better offer!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>React Data Fetching Pattern - Part III</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Wed, 16 Nov 2022 16:31:16 +0000</pubDate>
      <link>https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d</link>
      <guid>https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d</guid>
      <description>&lt;p&gt;This article is a continuation of &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-40mg"&gt;React Data Fetching Patterns - useState-useEffect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg"&gt;React Data Fetching Pattern - Custom Hook using Context API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;here&lt;/a&gt; to access the Github repo for the code examples discussed below.&lt;/p&gt;

&lt;h3&gt;Redux createAsyncThunk &lt;/h3&gt;

&lt;p&gt;While React Context API is suitable for smaller apps, we need a more performant solution for larger apps. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redux&lt;/strong&gt; provides a solution to the problem of unnecessary re-rendering of components posed by Context API, as Redux only re-renders the updated component. Within the &lt;code&gt;Redux-toolkit&lt;/code&gt; library, one has access to an API known as &lt;code&gt;createAsyncThunk&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;createAsyncThunk&lt;/code&gt; will accept a callback function that returns a promise - this is where the &lt;code&gt;getUsers&lt;/code&gt;API function will reside. Upon execution of the &lt;code&gt;createAsyncThunk&lt;/code&gt; function, similar to a Promise function, it will generate 3 types of actions: &lt;em&gt;pending&lt;/em&gt;, &lt;em&gt;fulfilled&lt;/em&gt;, &lt;em&gt;rejected&lt;/em&gt;, and the &lt;code&gt;users&lt;/code&gt; state will be updated accordingly depending on the action type.&lt;br&gt;
Below is an example of the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface UsersDataState {
  users: User[]
  loading: boolean
  error: string
}

const initialState: UsersDataState = {
  users: [] as User[],
  loading: false,
  error: "",
}

// set up createAsyncThunk function
export const getUsersData = createAsyncThunk("users/fetchUsers", () =&amp;gt; {
  return getUsers(apiURL).then(({results}) =&amp;gt; results)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {},

  extraReducers: (builder) =&amp;gt; {
// Pending - users state is not updated
    builder.addCase(getUsersData.pending, (state) =&amp;gt; {
      state.loading = true
    })

// Fulfilled - users state is updated
    builder.addCase(getUsersData.fulfilled, (state, action: PayloadAction&amp;lt;UserApi[]&amp;gt;) =&amp;gt; {
      state.users = action.payload
        .map((user: UserApi) =&amp;gt; {
          return {
            id: user.id.value,
            firstName: user.name.first,
            lastName: user.name.last,
            username: user.login.username,
            email: user.email,
          }
        })

      state.loading = false
    })

// Rejected - users state is an empty array
    builder.addCase(getUsersData.rejected, (state, action) =&amp;gt; {
      state.loading = false
      state.users = []
      state.error = action.error.message || "Something went wrong"
    })
  },
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a React component to have access to the &lt;code&gt;users&lt;/code&gt; state using Redux, one also has to set up a &lt;strong&gt;redux store&lt;/strong&gt; and then wrap the &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component with &lt;code&gt;Redux Provider&lt;/code&gt;. You may refer to the boilerplate code in the &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;repo here&lt;/a&gt; for further details.&lt;/p&gt;

&lt;p&gt;Having done the above, let's see how we can retrieve the data in the component for UI rendering.&lt;/p&gt;

&lt;p&gt;As shown below, within a React component, one has access to 2 redux hooks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useAppSelector&lt;/code&gt; - enable access to states&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useAppDispatch&lt;/code&gt; - enable update to states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can use &lt;code&gt;useEffect&lt;/code&gt; hook to trigger the data fetching and updating of the &lt;code&gt;users&lt;/code&gt; state. Then the state will be used for UI rendering.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function CardList() {
    const {users, loading, error} = useAppSelector((state) =&amp;gt; state.user)
    const dispatch = useAppDispatch()

    // update of users state with useEffect
    useEffect(() =&amp;gt; {
        dispatch(getUsersData())
    },[])

  return (
    &amp;lt;div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8"&amp;gt;
        {loading 
        ? &amp;lt;Loading /&amp;gt;
        : error 
        ? &amp;lt;ErrorFallBack /&amp;gt;
        : users.map((user:User) =&amp;gt; (&amp;lt;CardItem key={user.id} user={user}/&amp;gt;))
        }
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Pros&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;More Performant than Context API&lt;/em&gt;: As Redux avoids unnecessary re-rendering, the app is more performant as a result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Cons&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Complicated setup&lt;/em&gt;: As demonstrated above, there are a lot of boilerplate codes to set up redux slicer and store. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having discussed a few data fetching methods, could there be a solution that is both simple to set up and performant? Let's proceed to look at the next method - &lt;strong&gt;SWR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To be continued:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe"&gt;SWR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen"&gt;React Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on Redux &lt;code&gt;createAsyncThunk&lt;/code&gt;, see &lt;a href="https://redux-toolkit.js.org/api/createAsyncThunk"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>api</category>
    </item>
    <item>
      <title>React Data Fetching Patterns - Part II</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Wed, 16 Nov 2022 16:31:05 +0000</pubDate>
      <link>https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg</link>
      <guid>https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg</guid>
      <description>&lt;p&gt;This article is a continuation of:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-40mg"&gt;React Data Fetching Patterns - useState-useEffect&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;here&lt;/a&gt; to access the Github repo for the code examples discussed below.&lt;/p&gt;

&lt;h3&gt;Custom Hook using React Context API&lt;/h3&gt;

&lt;p&gt;To deal with the problem of prop-drilling, we could create a custom hook which utilises &lt;strong&gt;React Context API&lt;/strong&gt;. The &lt;code&gt;useState-useEffect&lt;/code&gt; data fetching logic can then reside within this hook. &lt;/p&gt;

&lt;p&gt;Using the example below, the &lt;code&gt;UserContext&lt;/code&gt; component will create the &lt;code&gt;users&lt;/code&gt; state, while &lt;code&gt;UserProvider&lt;/code&gt; stores the states and provides them to other components through &lt;code&gt;useContext&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface UserProps {
    users: User[],
    loading: boolean,
    error: boolean,
}

export const UserContext = createContext&amp;lt;UserProps&amp;gt;({
    users: [],
    loading: false,
    error: false
})

export const UserProvider = ({children}: {children: React.ReactNode}) =&amp;gt; {
    const [users, setUsers] = useState&amp;lt;User[]&amp;gt;([])
    const [error, setError] = useState(false)
    const [loading, setLoading] = useState(false)

    useEffect(() =&amp;gt; {
        setLoading(true)
        getUsers(apiURL)
            .then(({results:data}) =&amp;gt; {
                console.log({data})
                setUsers(
                    data.map((user:UserApi) =&amp;gt; {
                        return {
                            id: user.id.value,
                            firstName: user.name.first,
                            lastName: user.name.last,
                            username: user.login.username,
                            email: user.email,
                        }})
                    )
                })
            .catch(() =&amp;gt; setError(true))
            .finally(() =&amp;gt; setLoading(false))
    },[])

    // useMemo hook is used to `memoize` the value so that they only recompute when states have changed
    const value = useMemo(() =&amp;gt; ({
        users,
        loading,
        error
    }),[users, loading, error])

    return (
        &amp;lt;UserContext.Provider value={value}&amp;gt;
          {children}
        &amp;lt;/UserContext.Provider&amp;gt;
      )
}
// Provide access to other components through useUsers custom hook
export function useUsers() {
    return useContext(UserContext)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To provide access of the states to all the child components, we need to wrap  the &lt;code&gt;UserProvider&lt;/code&gt; around the top level component (&lt;code&gt;&amp;lt;App/&amp;gt;&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;UserProvider&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/UserProvider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a React component to access the states from &lt;code&gt;UserProvider&lt;/code&gt;, the custom hook can be imported, and the required data can be retrieved through the custom hook, as illustrated below. This will allow any React component to have access to a full or subset of the states without having to prop-drill.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useUsers } from '../hooks/useUsers';

export default function CardList() {
    const {users, loading, error} = useUsers()

  return (
    &amp;lt;div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8"&amp;gt;
        {loading 
            ? &amp;lt;Loading /&amp;gt;
            : error 
            ? &amp;lt;ErrorFallBack /&amp;gt;
            : users.map((user:User) =&amp;gt; (&amp;lt;CardItem key={`${user.id}${user.email}`} user={user}/&amp;gt;))
        }
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Pros&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Easy to setup&lt;/em&gt;: With the Context API, it is relatively easy to set up and use&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Easy to understand&lt;/em&gt;: The simple setup means that the code is also easily understandable&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Cons&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Unnecessary re-rendering&lt;/em&gt;: React will re-render all components whenever there is an update to the value of the props. For a larger app with thousands of components, this will slow down the performance of the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To deal with the issue of unnecessary component re-rendering and improve the performance of the app, let's proceed to look at the next data fetching method - &lt;strong&gt;Redux&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To be continued:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d"&gt;Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe"&gt;SWR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen"&gt;React Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more info on React Context, see &lt;a href="https://reactjs.org/docs/context.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactcontext</category>
      <category>reacthook</category>
      <category>api</category>
    </item>
    <item>
      <title>React Data Fetching Pattern - Part IV</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Wed, 16 Nov 2022 16:30:39 +0000</pubDate>
      <link>https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe</link>
      <guid>https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe</guid>
      <description>&lt;p&gt;This article is a continuation of &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-40mg"&gt;React Data Fetching Patterns - useState-useEffect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg"&gt;React Data Fetching Pattern - Custom Hook using Context API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d"&gt;React Data Fetching Pattern - Redux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;here&lt;/a&gt; to access the Github repo for the code examples discussed below.&lt;/p&gt;

&lt;h3&gt;SWR&lt;/h3&gt;

&lt;p&gt;From the previous discussions, we see that there are pros and cons with each data fetching method. Could there be a method that is both performant and easy to use? Enter &lt;strong&gt;SWR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SWR&lt;/strong&gt; is a relatively recent library created by Vercel, the same team that created NextJS. &lt;code&gt;SWR&lt;/code&gt; stands for &lt;em&gt;stale-while-revalidate&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SWR&lt;/code&gt; promises &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;to supply data to components &lt;strong&gt;constantly&lt;/strong&gt; and &lt;strong&gt;automatically&lt;/strong&gt;. And the UI will be always fast and reactive. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make the data fetching really easy, &lt;code&gt;SWR&lt;/code&gt; provides &lt;code&gt;useSWR&lt;/code&gt; hook which accepts an API url and a callback function (&lt;code&gt;fetcher&lt;/code&gt;) and then it returns &lt;em&gt;data&lt;/em&gt; and &lt;em&gt;error&lt;/em&gt;. There is also an option for &lt;code&gt;suspense:true&lt;/code&gt; with &lt;code&gt;useSWR&lt;/code&gt; hook, which allows for integration with the &lt;strong&gt;React Suspense API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;React &lt;code&gt;Suspense&lt;/code&gt; API will wait for the data to finish loading before showing the UI to a user. While waiting, a fallback component, such as &lt;code&gt;&amp;lt;Loading /&amp;gt;&lt;/code&gt; will be shown to the user.&lt;/p&gt;

&lt;p&gt;To make the code reusable and avoid prop-drilling, we can perform the data fetching in a custom hook (&lt;code&gt;useUsers&lt;/code&gt;), as below. We have to first define a &lt;code&gt;fetcher&lt;/code&gt; function, where the &lt;code&gt;getUsers&lt;/code&gt; function will reside. The &lt;code&gt;fetcher&lt;/code&gt; function will then be passed as a callback function to the &lt;code&gt;useSWR&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetcher = async (apiURL:string) =&amp;gt; {
    try{
        const {results:data} = await getUsers(apiURL)
        return data.map((user:UserApi) =&amp;gt; ({
            id: user.id.value,
            firstName: user.name.first,
            lastName: user.name.last,
            username: user.login.username,
            email: user.email,
        }))
    } catch(error) {
        throw new Error("unable to fetch data")
    }
}

const useUsers = () =&amp;gt; {
    const {data, error} = useSWR(apiURL, fetcher,{suspense:true})

    return ({
        users: data,
        loading: !data &amp;amp;&amp;amp; !error ? true : false,
        error: error
    })
}

export default useUsers;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;code&gt;useUsers&lt;/code&gt; hook set up, any react component will now have access to the &lt;code&gt;users&lt;/code&gt; state through the &lt;code&gt;useUsers&lt;/code&gt; hook, as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function CardList() {
  const { users } = useUsers()

  return (
    &amp;lt;div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8"&amp;gt;
      &amp;lt;Suspense fallback={&amp;lt;Loading /&amp;gt;}&amp;gt;
        {users.map((user:User) =&amp;gt; (&amp;lt;CardItem key={`${user.id}${user.email}`} user={user}/&amp;gt;))}
      &amp;lt;/Suspense&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Pros&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;As you can see from the codes above, &lt;code&gt;useSWR&lt;/code&gt; greatly simplifies the complexity of the initial code set up to fetch data, and this is done without compromising on performance (it is incredibly performant!). &lt;/li&gt;
&lt;li&gt;Besides the advantages above, &lt;strong&gt;SWR&lt;/strong&gt; also provides other utilities such as data refetching &amp;amp; prefetching, conditional fetching, caching and data refresh interval config.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, at this point, I would also like to introduce an alternative library that provides similar utilities as SWR - &lt;strong&gt;React Query&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To be continued:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen"&gt;React Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on SWR, see &lt;a href="https://swr.vercel.app/docs/getting-started"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>swr</category>
      <category>api</category>
    </item>
    <item>
      <title>React Data Fetching Pattern - Part V</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Wed, 16 Nov 2022 16:30:18 +0000</pubDate>
      <link>https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen</link>
      <guid>https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen</guid>
      <description>&lt;p&gt;This article is a continuation of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-40mg"&gt;React Data Fetching Patterns - useState-useEffect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg"&gt;React Data Fetching Pattern - Custom Hook using Context API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d"&gt;React Data Fetching Pattern - Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe"&gt;SWR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;here&lt;/a&gt; to access the Github repo for the code examples discussed below.&lt;/p&gt;

&lt;h3&gt;React Query&lt;/h3&gt;

&lt;p&gt;An alternative React data fetching library that provides similar utilities as &lt;strong&gt;SWR&lt;/strong&gt; is &lt;strong&gt;React Query&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;React Query provides a hook called &lt;code&gt;useQuery&lt;/code&gt; which accepts a query key and a callback function (&lt;code&gt;fetcher&lt;/code&gt;). Similar to SWR, it also allows for integration with &lt;code&gt;React Suspense&lt;/code&gt; API by simply including the option &lt;code&gt;suspense: true&lt;/code&gt;. If the &lt;code&gt;fetcher&lt;/code&gt; callback requires a parameter (eg: URL), we can include this as a 2nd item in the array after the query key. &lt;code&gt;useQuery&lt;/code&gt; will return &lt;em&gt;data&lt;/em&gt;, &lt;em&gt;isLoading&lt;/em&gt;, &lt;em&gt;error&lt;/em&gt;, &lt;em&gt;isError&lt;/em&gt; to be accessed by React components.&lt;/p&gt;

&lt;p&gt;To allow for code reusability and avoid prop-drilling, we can create a custom hook to perform the logic of data fetching using React Query, as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetcher = async(apiURL:string) =&amp;gt; {
    try {
      const {results: data} = await getUsers(apiURL)
      return data.map((user:UserApi) =&amp;gt; ({
          id: user.id.value,
          firstName: user.name.first,
          lastName: user.name.last,
          username: user.login.username,
          email: user.email,  
      }))
    } catch(error) {
      throw new Error('unable to fetch data')
    }
}

const useUsers = () =&amp;gt; {
    const {isLoading, isError, data, error} = useQuery(['users',apiURL], () =&amp;gt; fetcher(apiURL),{suspense: true})

    return ({
        users: data,
        isLoading,
        isError,
        error
    })
}

export default useUsers;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we can access the data in any React component, we have to wrap the &lt;code&gt;QueryClientProvider&lt;/code&gt; around the top-level component (&lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { QueryClientProvider, QueryClient } from 'react-query';

const queryClient = new QueryClient()

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within React component, we can now access the &lt;code&gt;users&lt;/code&gt; state from &lt;code&gt;useUsers&lt;/code&gt; hook, as below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function CardList() {
  const {users} = useUsers()

  return (
    &amp;lt;div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8"&amp;gt;
      &amp;lt;Suspense fallback={&amp;lt;Loading /&amp;gt;}&amp;gt;
        {
          users.map((user:User) =&amp;gt; (&amp;lt;CardItem key={user.id} user={user}/&amp;gt;))
        }
      &amp;lt;/Suspense&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Pros&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Similar to &lt;strong&gt;SWR&lt;/strong&gt;, the initial code set-up is relatively easy and it is also performant.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on &lt;code&gt;React Query&lt;/code&gt;, see &lt;a href="https://tanstack.com/query/v4/docs/adapters/react-query"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope these article provides valuable information to you as a React developer. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactquery</category>
      <category>api</category>
    </item>
    <item>
      <title>React Data Fetching Patterns - Part I</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Wed, 16 Nov 2022 12:09:23 +0000</pubDate>
      <link>https://dev.to/francisldn/react-data-fetching-patterns-40mg</link>
      <guid>https://dev.to/francisldn/react-data-fetching-patterns-40mg</guid>
      <description>&lt;p&gt;In React, &lt;strong&gt;data fetching&lt;/strong&gt; from an external API typically involves a few steps, as below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;send a fetch request&lt;/li&gt;
&lt;li&gt;await for response&lt;/li&gt;
&lt;li&gt;receive the requested data or error&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we will first discuss how data fetching is traditionally done in React using &lt;code&gt;useState-useEffect&lt;/code&gt; hooks. We will then proceed to discuss other data fetching patterns, utilising &lt;a href="https://reactjs.org/blog/2022/03/29/react-v18.html"&gt;Suspense&lt;/a&gt; - an API made available in React v18 (no longer experimental), as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg"&gt;Custom hook using Context API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d"&gt;Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe"&gt;SWR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen"&gt;React Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click &lt;a href="https://github.com/francisldn/React-Data-Fetching-Patterns"&gt;here&lt;/a&gt; to access the Github repo for the code examples discussed below.&lt;/p&gt;

&lt;h3&gt;How data fetching is traditionally done&lt;/h3&gt;

&lt;p&gt;In React, we traditionally perform data fetching using &lt;code&gt;useState-useEffect&lt;/code&gt; hooks. Within a React component, a state is created using &lt;code&gt;useState&lt;/code&gt; hook to store data. &lt;code&gt;useEffect&lt;/code&gt; hook is executed as the component first mounts or page first renders. The data fetching logic in the useEffect hook will run and data will be stored as a state.&lt;/p&gt;

&lt;p&gt;Let's go through the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;users&lt;/code&gt; state is declared with &lt;code&gt;useState&lt;/code&gt;, together with loading and error states&lt;/li&gt;
&lt;li&gt;Within &lt;code&gt;useEffect&lt;/code&gt;, &lt;code&gt;getUsers&lt;/code&gt; function will execute on component mounts, and the loading state will set to true while waiting for data to be retrieved&lt;/li&gt;
&lt;li&gt;On successful data retrieval, the loading and error states will set to false, and &lt;code&gt;users&lt;/code&gt; state will contain the retrieved data, ready for UI rendering.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function CardList() {
    const [users, setUsers] = useState&amp;lt;User[]&amp;gt;([])
    const [isLoading, setLoading] = useState(false)
    const [isError, setError] = useState(false)

    useEffect(() =&amp;gt; { 
        setLoading(true)  
        getUsers(apiURL)
            .then(({results:data}) =&amp;gt; {
                setUsers(
                data.map((user:UserApi) =&amp;gt; {
                    return {
                        id: user.id.value,
                        firstName: user.name.first,
                        lastName: user.name.last,
                        username: user.login.username,
                        email: user.email,
                    }}))
                })
            .catch(() =&amp;gt; setError(true))
            .finally(() =&amp;gt; setLoading(false))
    },[])

  return (
    &amp;lt;div className="grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 justify-center grid-cols-1 mt-8"&amp;gt;
        {isLoading 
        ? &amp;lt;Loading /&amp;gt;
        : isError 
        ? &amp;lt;ErrorFallBack /&amp;gt;
        : users.map((user:User) =&amp;gt; (&amp;lt;CardItem key={user.id} user={user}/&amp;gt;))
        }
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;Downsides&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Prop-drilling&lt;/em&gt;&lt;br&gt;
While this data fetching pattern works fine for a local component, if there were multiple components that require access to the same set or a subset of the data, then we will need to pass the props through multiple child components, which could lead to &lt;a href="https://kentcdodds.com/blog/prop-drilling"&gt;problems of prop-drilling&lt;/a&gt;. For a larger app, prop-drilling through multiple layers of components can make the app unwieldy and hard to manage. &lt;/p&gt;

&lt;p&gt;To overcome the issues outlined above, let's proceed to look at a few other data fetching methods, as below.&lt;/p&gt;

&lt;p&gt;To be continued:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-patterns-part-ii-10gg"&gt;Custom hook using Context API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iii-584d"&gt;Redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-iv-3mbe"&gt;SWR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/francisldn/react-data-fetching-pattern-part-v-2oen"&gt;React Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>swr</category>
      <category>redux</category>
      <category>reactquery</category>
    </item>
    <item>
      <title>Managing State with React useContext</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Sun, 24 Apr 2022 17:52:12 +0000</pubDate>
      <link>https://dev.to/francisldn/managing-state-with-react-usecontext-346k</link>
      <guid>https://dev.to/francisldn/managing-state-with-react-usecontext-346k</guid>
      <description>&lt;p&gt;This is a short post to explain how one can use React &lt;code&gt;useContext&lt;/code&gt; hook to create global state variables, thus allowing for props to be passed onto different components easily and avoiding "prop-drilling".&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up Context file
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a context component using &lt;code&gt;createContext&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {createContext, useState} from 'react'

export const LoginContext = createContext({});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrap components with &lt;code&gt;Context.Provider&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wrap all components within &lt;code&gt;LoginContext&lt;/code&gt;. All components will have access to the LoginContext props.&lt;/li&gt;
&lt;li&gt;Note that the props are passed in using &lt;strong&gt;&lt;code&gt;{{double curly braces}}&lt;/code&gt;&lt;strong&gt;.
&lt;/strong&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {LoginContext} from './Context'

export function App() {
  const [loggedIn, setLoggedIn] = useState(false)

  return(
    &amp;lt;LoginContext.Provider value={{loggedIn, setLoggedIn}}&amp;gt;
       &amp;lt;Home /&amp;gt;
       &amp;lt;Login /&amp;gt;
       &amp;lt;Profile /&amp;gt;
    &amp;lt;/LoginContext.Provider&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passing props to components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pass &lt;code&gt;loggedIn&lt;/code&gt; and &lt;code&gt;setLoggedIn&lt;/code&gt; to &lt;code&gt;Login&lt;/code&gt; component&lt;/li&gt;
&lt;li&gt;Login component can access the props from LoginContext through &lt;code&gt;useContext&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Note the use of &lt;code&gt;{curly braces}&lt;/code&gt; instead of &lt;code&gt;[square brackets]&lt;/code&gt; for props destructuring.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {LoginContext} from '../Context';
import React, {useContext} from 'react';

export const Login = () =&amp;gt; {
   const {loggedIn, setLoggedIn} = useContext(LoginContext);

   return (
      &amp;lt;div&amp;gt;
         &amp;lt;button onClick={() =&amp;gt; setLoggedIn(!loggedIn)}&amp;gt;Click 
           here to login
         &amp;lt;/button&amp;gt;
         {loggedIn? &amp;lt;h1&amp;gt;You are logged in&amp;lt;/h1&amp;gt;: &amp;lt;h1&amp;gt;You are 
         not logged in&amp;lt;/h1&amp;gt;}
      &amp;lt;/div&amp;gt; 
   )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>hooks</category>
      <category>frontend</category>
    </item>
    <item>
      <title>5 Tips &amp; Tricks for DeFi Developers from the UniswapV2 Contracts Review</title>
      <dc:creator>Francisldn</dc:creator>
      <pubDate>Sat, 22 Jan 2022 15:44:29 +0000</pubDate>
      <link>https://dev.to/francisldn/5-tips-tricks-in-uniswapv2-contracts-for-defi-developers-32oa</link>
      <guid>https://dev.to/francisldn/5-tips-tricks-in-uniswapv2-contracts-for-defi-developers-32oa</guid>
      <description>&lt;p&gt;&lt;strong&gt;Uniswap&lt;/strong&gt; announced their V2 launch on Ethereum mainnet on 18 May 2020, followed by the V3 launch on 5 May 2021. With a total value locked (TVL)of USD 7.4 billion (as of 21 Jan 2022), Uniswap V2 accounted for slightly more than half of the total Uniswap TVL (USD 3.6 billion), with an average daily trading volume of around USD 500 million. Clearly, Uniswap V2 remains a highly popular decentralised exchange (DEX) among DeFi users. &lt;/p&gt;

&lt;p&gt;Having recently reviewed the Uniswap V2 contracts, I found the contracts full of gems which are worth sharing with fellow DeFi smart contract developers. &lt;/p&gt;

&lt;h2&gt;
  
  
  Brief Overview of Contracts
&lt;/h2&gt;

&lt;p&gt;Uniswap V2 contracts are organised into &lt;strong&gt;V2 Core&lt;/strong&gt; and &lt;strong&gt;V2 Periphery&lt;/strong&gt;. V2 Core consists of the essential V2 smart contracts, including &lt;em&gt;UniswapV2Pair&lt;/em&gt;, &lt;em&gt;UniswapV2Factory&lt;/em&gt; and &lt;em&gt;UniswapV2ERC20&lt;/em&gt;. V2 Periphery consists of a set of helper contracts or functions which include &lt;em&gt;UniswapV2Migrator&lt;/em&gt;, &lt;em&gt;UniswapV2Router&lt;/em&gt; and a number of libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  UniswapV2 Core
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;UniswapV2Pair&lt;/em&gt; - responsible for the maintenance of liquidity pool and token swapping functionality. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;UniswapV2Factory&lt;/em&gt; -  responsible for the creation of token pair liquidity pools and the setting of liquidity provider fee. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;UniswapV2ERC20&lt;/em&gt; -  implements the ERC20 token interface but with an additional feature, this is something which I will explore a bit more later. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  UniswapV2 Periphery
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;UniswapV2Router01&lt;/em&gt; and 02 - acts as a wrapper for V2Pair, handling liquidity addition and removal operations and token swapping functionalities. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;UniswapV2Migrator&lt;/em&gt; - provides liquidity migration service from Uniswap V1 to V2.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Review of Source Code
&lt;/h2&gt;

&lt;p&gt;Below are some of the interesting tips and tricks implemented in UniswapV2.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. ERC-20-Permit - a gas-efficient version of ERC-20
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With a standard ERC-20 token, a tokenholder needs to execute &lt;code&gt;approve&lt;/code&gt; transaction prior to executing &lt;code&gt;transferFrom&lt;/code&gt;. The &lt;code&gt;approve&lt;/code&gt; function must be performed by an Externally-Owned Wallet (EOA) and this is meant to protect user's wallet from being drained by a malicious contract. But this also leads to degradation of user experience, as it means that a user would need to execute 2 transactions: &lt;code&gt;approve&lt;/code&gt; and &lt;code&gt;transferFrom&lt;/code&gt; to transfer a token, which is not gas-efficient. So can we implement a more gas-efficient version of ERC20 token while retain the security for user's funds?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: With the addition of &lt;code&gt;permit&lt;/code&gt; function, Uniswap implements offline signature for the approval of token transfer, which is gas-less. The signature can then be used for on-chain execution of &lt;code&gt;transferFrom&lt;/code&gt; function (or any other functions). The &lt;code&gt;permit&lt;/code&gt; function is also used in the V2 Router contract for user to withdraw liquidity from a liquidity pool (eg.&lt;code&gt;removeLiquidityWithPermit&lt;/code&gt; function). &lt;/p&gt;

&lt;p&gt;To prevent replay attack using the same signature multiple times (given it is done off-chain), a valid signature would consist of a few safeguards such as a clear definition of scope for the signature as defined in &lt;code&gt;DOMAIN_SEPARATOR&lt;/code&gt; and &lt;code&gt;PERMIT_TYPEHASH&lt;/code&gt; with non-reusable nonce which increments with every signature. The signature uses EIP-712 standard for signing and the ERC-20 implementation of permit extension follows EIP-2612 standard.&lt;/p&gt;

&lt;p&gt;Smart contract developers who are interested in implementing or learning more about ERC-20-Permit may refer to the resources below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/draft-ERC20Permit.sol" rel="noopener noreferrer"&gt;Openzeppelin ERC-20-Permit (in draft status)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soliditydeveloper.com/erc20-permit" rel="noopener noreferrer"&gt;A Long Way To Go: On Gasless Tokens and ERC20-Permit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://eips.ethereum.org/EIPS/eip-712" rel="noopener noreferrer"&gt;EIP-712&lt;/a&gt; and &lt;a href="https://eips.ethereum.org/EIPS/eip-2612" rel="noopener noreferrer"&gt;EIP-2612&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forum.openzeppelin.com/t/why-is-erc20permit-better-than-approve-transferfrom/7478" rel="noopener noreferrer"&gt;https://forum.openzeppelin.com/t/why-is-erc20permit-better-than-approve-transferfrom/7478&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. CREATE2 - creation of pair addresses
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;There are 2 ways to create a new contract on EVM-compatible chain - &lt;code&gt;CREATE&lt;/code&gt; and &lt;code&gt;CREATE2&lt;/code&gt;. In the UniswapV2Pair contract, &lt;code&gt;CREATE2&lt;/code&gt; opcode (in assembly) is used to create a token pair liquidity pool address, which is a change from the V1 contract (where &lt;code&gt;CREATE&lt;/code&gt; is used). &lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE&lt;/code&gt; opcode is used to compute deployed contract address like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;keccak256(senderAddress, nonce)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In Solidity, one can also create a new contract through &lt;code&gt;new&lt;/code&gt; keyword, as below. Instantiating a new contract in this way uses the &lt;code&gt;CREATE&lt;/code&gt; opcode, and contract address cannot be pre-determined in a deterministic manner (due to the use of nonce).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pair = new UniswapV2Pair()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;CREATE2&lt;/code&gt; opcode computes pre-determined contract address like so:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;keccak256(0xFF, senderAddress, salt, bytecode)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0xFF&lt;/code&gt; is a constant to prevent collision with the CREATE function&lt;/li&gt;
&lt;li&gt;senderAddress - sender's own address&lt;/li&gt;
&lt;li&gt;salt - an arbitrary value provided by the sender&lt;/li&gt;
&lt;li&gt;bytecode - contract's bytecode to be deployed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The advantage of &lt;code&gt;CREATE2&lt;/code&gt; vs &lt;code&gt;CREATE&lt;/code&gt; is that with &lt;code&gt;CREATE2&lt;/code&gt;, contract address can be pre-computed off-chain (therefore gas-less) and one can then send ETH to the pre-computed contract address even before the contract is deployed on-chain. One such use case is that a developer may distribute a pre-computed contract address to a user in advance without having to deploy the contract, and the contract can then be initialised when a user starts sending funds to it, thus allowing for gas fee saving.&lt;/p&gt;

&lt;p&gt;To learn more about deploying contract using &lt;code&gt;CREATE2&lt;/code&gt;, below are some resources for your reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/miguelmota/solidity-create2-example" rel="noopener noreferrer"&gt;https://github.com/miguelmota/solidity-create2-example&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openzeppelin.com/cli/2.8/deploying-with-create2" rel="noopener noreferrer"&gt;Openzeppelin CREATE2 CLI &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ethereum.stackexchange.com/questions/92491/instantiating-a-smart-contract-in-uniswap-using-assembly-and-create2" rel="noopener noreferrer"&gt;https://ethereum.stackexchange.com/questions/92491/instantiating-a-smart-contract-in-uniswap-using-assembly-and-create2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eips.ethereum.org/EIPS/eip-1014" rel="noopener noreferrer"&gt;EIP-1014: Skinny CREATE2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  3. Time-Weighted Average Price update
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the UniswapV2Pair contract, token prices are updated based on time-weighted average prices (TWAP) mechanism. The way it works is that each transacted price is weighted by the time that has passed since the last block in which it was updated and the historical prices are then accumulated. This increases the difficulty and reduces the incentive to manipulate prices on Uniswap, especially for tokens with high trading volume. This is an improvement from Uniswap V1. The diagram below gives a good overview of the TWAP price mechanism (courtesy of Uniswap).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqndvzjlzg91ro05t6zs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqndvzjlzg91ro05t6zs.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Given the improvement in price update mechanism in V2, which is more resistant to price manipulation, Uniswap V2 can therefore serve as an on-chain price oracle for other DApps. Uniswap has actually created the &lt;a href="https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2OracleLibrary.sol" rel="noopener noreferrer"&gt;&lt;em&gt;UniswapV2OracleLibrary&lt;/em&gt;&lt;/a&gt; exactly for such purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implications&lt;/strong&gt;&lt;br&gt;
As the token prices are not updated based on the actual reserve balance in the liquidity pool, there will exist discrepancies between the token balance calculated based on TWAP mechanism and the actual reserve balance. There are also tokens with deflationary or inflationary implementations which could lead to discrepancies in token balances. Tokens with balances greater than 2&lt;sup&gt;112&lt;/sup&gt; will also lead to overflow of the storage slots for reserves, which could lead to failed trades. For all the cases mentioned above (not exhaustive), users can withdraw excess token balances or reserves through &lt;code&gt;skim&lt;/code&gt; and &lt;code&gt;sync&lt;/code&gt; functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Fixed Point Binary Library (UQ112x112.sol)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;library UQ112x112 {
    uint224 constant Q112 = 2**112;

    // encode a uint112 as a UQ112x112
    function encode(uint112 y) internal pure returns (uint224 z) {
        z = uint224(y) * Q112; // never overflows
    }

    // divide a UQ112x112 by a uint112, returning a UQ112x112
    function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
        z = x / uint224(y);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Solidity lacks support for non-integer numeric types (such as fractions)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: To overcome the problem above, Uniswap V2 uses the above library to handle fixed point binary numbers for updating prices. With fixed point binary numbers, there is a trade-off between range and precision, the higher the range of numbers, the lower the precision. In the case of Uniswap, the fixed point binary numbers are implemented as uint224, where the first 112 bits represent integers and the last 112 bits represent decimals. This means the numbers would have a range of [0, 2&lt;sup&gt;112&lt;/sup&gt;-1] and a precision of &lt;sup&gt;1&lt;/sup&gt;⁄112.&lt;/p&gt;

&lt;p&gt;Readers who would like to learn more about fixed point binary numbers may refer to the excellent explanation in the video below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=QFlbvSeBkwY" rel="noopener noreferrer"&gt;Fixed Point Binary Fractions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Lock
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uint private unlocked = 1;

    modifier lock() {
        require(unlocked == 1, 'UniswapV2: LOCKED');
        unlocked = 0;
        _;
        unlocked = 1;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uniswap uses the &lt;code&gt;lock&lt;/code&gt; modifier as a measure to prevent reentrancy attack. The most high profile reentrancy attack occurred in 2016 where the attacker drained 3.6 million ether from The DAO. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;lock&lt;/code&gt; modifier prevents reentrancy attack by setting the initial value of &lt;code&gt;unlocked&lt;/code&gt; state variable to 1. Once a function with &lt;code&gt;lock&lt;/code&gt; modifier is executed, the &lt;code&gt;unlocked&lt;/code&gt; state variable value will be set to 0. To reenter the contract, the &lt;code&gt;unlocked&lt;/code&gt; state variable is required to be == 1, thus preventing reentrancy. The &lt;code&gt;unlocked&lt;/code&gt; state variable value will return to 1 upon successful execution of the function or failed execution (reversion to original state). Uniswap applies the &lt;code&gt;lock&lt;/code&gt; modifier to all the &lt;em&gt;UniswapV2Pair&lt;/em&gt; functions that perform external calls, such as &lt;code&gt;mint&lt;/code&gt;, &lt;code&gt;burn&lt;/code&gt;, &lt;code&gt;swap&lt;/code&gt; and &lt;code&gt;skim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Developers may also refer to the Openzeppelin contract suite for a &lt;a href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol" rel="noopener noreferrer"&gt;similar implementation&lt;/a&gt; of reentrancy guard.&lt;/p&gt;

&lt;p&gt;Further resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/coinmonks/protect-your-solidity-smart-contracts-from-reentrancy-attacks-9972c3af7c21" rel="noopener noreferrer"&gt;Protect Your Solidity Smart Contracts From Reentrancy Attacks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol" rel="noopener noreferrer"&gt;Openzeppelin ReentrancyGuard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;If you like the content, please hit the like button so that it can reach more people.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>solidity</category>
      <category>uniswap</category>
      <category>smartcontract</category>
    </item>
  </channel>
</rss>
