<?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: Kris Grint</title>
    <description>The latest articles on DEV Community by Kris Grint (@krsgrnt).</description>
    <link>https://dev.to/krsgrnt</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%2F168337%2F940a3eef-782d-4b71-844e-a35d36a4efd2.jpg</url>
      <title>DEV Community: Kris Grint</title>
      <link>https://dev.to/krsgrnt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/krsgrnt"/>
    <language>en</language>
    <item>
      <title>Making sense of closure in JavaScript with React Hooks</title>
      <dc:creator>Kris Grint</dc:creator>
      <pubDate>Thu, 23 May 2019 20:19:25 +0000</pubDate>
      <link>https://dev.to/krsgrnt/making-sense-of-closure-in-javascript-with-react-hooks-2c74</link>
      <guid>https://dev.to/krsgrnt/making-sense-of-closure-in-javascript-with-react-hooks-2c74</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A closure is the combination of a function and the lexical environment within which that function was declared. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures"&gt;MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What do we really mean when we talk about closure in JavaScript? Closure occurs when an inner function has access to variables scoped to the outer function, even after the outer function has returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const outerFunction = () =&amp;gt; {
    const firstName = 'John';
    const secondName = 'Doe';

    const innerFunction = () =&amp;gt; {
        console.log(`${firstName} ${secondName}`);
    };

    return innerFunction;
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the example above, &lt;em&gt;outerFunction&lt;/em&gt; is comprised of two variables and a second function. When the function is run, it will return &lt;em&gt;innerFunction&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const closureExample = outerFunction();
closureExample();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By assigning the returned inner function to a variable called closureExample and then executing it, we will see the values of firstName and lastName logged out to the console. This is because innerFunction has closure over outerFunction: it has access to its properties even after the function where they were scoped to has been executed.&lt;/p&gt;

&lt;p&gt;The new Hooks API in React is a great example of closure in action. One of these hooks, useEffect(), is used to execute code after your component has finished rendering. It's similar to React's &lt;em&gt;componentDidMount&lt;/em&gt; lifecycle method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect } from 'react';

const Header = props =&amp;gt; {
    const { pageTitle, headerTitle } = props;

    useEffect(() =&amp;gt; {
        document.title = headerTitle;
        return () =&amp;gt; {
            document.title = pageTitle;
        }
    });

    return (
        &amp;lt;h1&amp;gt;{headerTitle}&amp;lt;/h1&amp;gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the example above, our Header component receives two props called headerTitle and pageTitle and returns the former surrounded by h1 tags. After rendering the heading, the useEffect() hook calls a function which will also set the title of the document to headerTitle. The function passed to useEffect() &lt;em&gt;itself returns a function&lt;/em&gt; which, when called, will change the title of the document to pageTitle.&lt;/p&gt;

&lt;p&gt;Because the useEffect() hook will run the function passed to it after the component has returned, but the function sets the title of the document to a property scoped to that component, we can say that it has closure over the component's properties. A second instance of closure occurs when React calls the function which was itself returned from this function, which will occur after the component is unmounted from the DOM in a way similar to the &lt;em&gt;componentWillUnmount&lt;/em&gt; lifecycle method. This final function sets the document title to the value of pageTitle, also scoped to the component which has long since returned. This pattern is a good way of 'cleaning up' after your component, as you can do things like reset values to their defaults or cancel outbound fetch requests.&lt;/p&gt;

&lt;p&gt;For the longest time, closure in JavaScript has been more of a question to catch out developers in job interviews than a feature of the language with practical value. With React's Hooks API, it's becoming a lot easier to see examples of this concept in the wild.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>closure</category>
      <category>react</category>
      <category>hooks</category>
    </item>
    <item>
      <title>Safely copying nested objects in JavaScript</title>
      <dc:creator>Kris Grint</dc:creator>
      <pubDate>Thu, 16 May 2019 22:03:31 +0000</pubDate>
      <link>https://dev.to/krsgrnt/safely-copying-nested-objects-in-javascript-5fpi</link>
      <guid>https://dev.to/krsgrnt/safely-copying-nested-objects-in-javascript-5fpi</guid>
      <description>&lt;p&gt;A fundamental concept when managing state in JavaScript is that you should never mutate the data directly. In large applications, respecting this rule can become difficult when state is stored in nested objects. This is particularly relevant if you are using libraries such as Redux, &lt;a href="https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns"&gt;as the docs suggest&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The key to updating nested data is that every level of nesting must be copied and updated appropriately. This is often a difficult concept for those learning Redux, and there are some specific problems that frequently occur when trying to update nested objects. These lead to accidental direct mutation, and should be avoided.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In order to avoid mutating state directly, we need to make a copy of the object, modify it as appropriate, and then use it in place of the original. This is the principle behind React's &lt;em&gt;setState&lt;/em&gt; method, which accepts an object which it will swap for the existing one in your component's state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference vs. value types in JavaScript
&lt;/h2&gt;

&lt;p&gt;JavaScript objects are data types which are passed by reference to the location in memory, as opposed to strings or integers which are passed by their actual value. This means that copying objects can be tricky, because assignment might not work as you expect.&lt;/p&gt;

&lt;p&gt;Take this example of a user object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const state = {
    name: 'John',
    address: {
        city: 'London',
        country: {
            countryName: 'United Kingdom',
            countryCode: 'UK',
        },
    },
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We cannot make a copy of this object by assigning it to a new variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const copyState = state;
copyState.name = 'Jane';
console.log(copyState === state); // true
console.log(state.name); // 'Jane'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The copyState variable is pointing to the same reference as the original state object, which is why the strict equals check returns true. When we modify the name property of the copyState object, we are mutating the same object which the state variable is pointing to. Often this is not what is intended.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spread operator
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax"&gt;spread operator or syntax&lt;/a&gt; (...) can be used to make a shallow copy of an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const shallowCopyState = { ...state };
shallowCopyState.name = 'Jane';
console.log(shallowCopyState === state); // false
console.log(state.name); // 'John'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, our two variables are pointing to different object references. Modifying the value of the name property on the shallowCopyState object has no effect on the original state object and the strict equals check returns false.&lt;/p&gt;

&lt;p&gt;Shallow in this context means that for any given object that is spread, the uppermost level of the new variable is an object containing the same properties and values of the original object, but at a new reference in memory. Any lower level or nested objects, however, will remain pointing to their original references:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const shallowCopyState = { ...state };
console.log(shallowCopyState === state); // false
shallowCopyState.address.city = 'Paris';
console.log(shallowCopyState.address === state.address); // true
console.log(state.address.city); // 'Paris'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To copy a deep object like our user object safely, we also need to use the spread operator at the nested level of the object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const deeperCopyState = {
    ...state,
    address: {
        ...state.address,
    },
};
deeperCopyState.address.country.countryCode = 'FR';
console.log(deeperCopyState.address === state.address); // false
console.log(deeperCopyState.address.country === state.address.country); // true
console.log(state.address.country.countryCode); // 'FR'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see in the above example, the nested object for address is different across the two variables, but its nested object for country  is &lt;em&gt;still&lt;/em&gt; pointing to the same reference as in our original state variable. We could fix this by going down further, but at this point it may be easier to reach for a library to help us, such as Immer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immer
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/immerjs/immer%5D"&gt;Immer library&lt;/a&gt; consists of a &lt;em&gt;produce&lt;/em&gt; function which takes an existing object and returns a new one. Because you can also dictate which properties on the new object will be updated, it's an excellent way of safely creating state objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const state = {
    name: 'John',
    address: {
        city: 'London',
        country: {
            countryName: 'United Kingdom',
            countryCode: 'UK',
        },
    },
};

const immerState = immer.produce(state, draftState =&amp;gt; {
    draftState.name = 'Jane';
    draftState.address.city = 'Paris';
    draftState.address.country.countryName = 'France';
    draftState.address.country.countryCode = 'FR';
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The immerState variable is completely decoupled to the original state object, and shares no references to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(immerState === state); // false
console.log(immerState.address === state.address); // false
console.log(immerState.address.country === state.address.country); // false
console.log(state.address.country.countryCode); // 'UK'
console.log(immerState.address.country.countryCode); // 'FR'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Finally
&lt;/h2&gt;

&lt;p&gt;It's worth referring back to the Redux docs about nested objects:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Obviously, each layer of nesting makes this harder to read, and gives more chances to make mistakes. This is one of several reasons why you are encouraged to keep your state flattened.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you find yourself handling objects that are many levels deep, and which require extensive use of the spread operator or a library like Immer, it is worth considering if there's a way to simplify the composition of such objects. If, however, you find yourself in a codebase where these structures are common, hopefully this article will help you keep your state immutable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/krsgrnt/f8f56141ebe463c0e9f167543de5c918"&gt;Above code examples are on a GitHub gist&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>immutability</category>
      <category>redux</category>
    </item>
  </channel>
</rss>
