<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Michael Jackson on Medium]]></title>
        <description><![CDATA[Stories by Michael Jackson on Medium]]></description>
        <link>https://medium.com/@mjackson?source=rss-7f9567e0d71c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*8O31mcWy-1mXcmnbnhz1-Q.jpeg</url>
            <title>Stories by Michael Jackson on Medium</title>
            <link>https://medium.com/@mjackson?source=rss-7f9567e0d71c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 03:17:59 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mjackson/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Use a Render Prop!]]></title>
            <link>https://medium.com/@mjackson/use-a-render-prop-50de598f11ce?source=rss-7f9567e0d71c------2</link>
            <guid isPermaLink="false">https://medium.com/p/50de598f11ce</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[design-patterns]]></category>
            <dc:creator><![CDATA[Michael Jackson]]></dc:creator>
            <pubDate>Mon, 18 Sep 2017 16:11:49 GMT</pubDate>
            <atom:updated>2018-02-08T01:43:04.770Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Update: </em><a href="https://github.com/facebook/react/pull/10741"><em>I made a PR to add Render Props to the official React docs</em></a><em>.</em></p><p><em>Update 2: Added some language to clarify that “children as a function” is the same concept, just a different prop name.</em></p><p><em>Update 3: </em><a href="https://github.com/facebook/react/pull/11818"><em>Render props are being used in React’s new context API</em></a><em>, patterned after </em><a href="https://github.com/ReactTraining/react-broadcast"><em>react-broadcast</em></a><em>!</em></p><p>A few months ago, I tweeted:</p><h3>MJ on Twitter</h3><p>@reactjs I can do anything you&#39;re doing with your HOC using a regular component with a render prop. Come fight me.</p><p>I was suggesting that the <a href="https://facebook.github.io/react/docs/higher-order-components.html">higher-order component pattern</a> that is a popular method of code reuse in many React codebases could be replaced 100% of the time with a regular component with a “render prop”. The “come fight me” part was a friendly taunt to the rest of the React community, and a good discussion ensued, but I was ultimately frustrated by my inability to fully express what I was trying to say in bursts of 140 chars apiece. I <a href="https://twitter.com/mjackson/status/885918220154134528">determined instead that I’d need to write something longer</a> at some point in the future to really do it justice.</p><p>When <a href="https://twitter.com/tylercollier">Tyler</a> invited me to speak at the <a href="https://www.meetup.com/Phoenix-ReactJS/events/242296327/">Phoenix ReactJS meetup</a> two weeks ago, I thought it’d be a great chance to explore the idea further. I was already going to be in Phoenix running <a href="https://reacttraining.com/">our React Fundamentals and Advanced React workshops</a> that week, and I’d heard great things about the meetup from my business partner <a href="https://medium.com/u/162352c45b6e">Ryan</a> who <a href="https://www.youtube.com/watch?v=hEGg-3pIHlE">spoke there in April</a>.</p><p>At the meetup, I gave a talk with the most click-bait-y title (sorry!) I could think of: <em>Never Write Another HOC</em>. You can watch the talk <a href="https://www.youtube.com/watch?v=BcVAq3YFiuc">on Phoenix ReactJS’ YouTube channel</a>, or in the embed below:</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FBcVAq3YFiuc%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DBcVAq3YFiuc&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FBcVAq3YFiuc%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/a593086aef40326eba135e5931fe3917/href">https://medium.com/media/a593086aef40326eba135e5931fe3917/href</a></iframe><p>What follows is a brief summary of the talk in case you’d prefer to read it without watching the video. But seriously: watch the video. It’s more fun. 😀</p><p>If you skip the video and start reading, but you don’t quite grasp what I’m talking about, please <em>go watch the video</em> instead. There’s a lot more nuance in the spoken word!</p><h3>The Problem with Mixins</h3><p>I started the talk by discussing the main problem that higher-order components were designed to solve: <strong>code reuse</strong>.</p><p>Let’s back up a little bit to 2015–to the days of React.createClass. Let’s say you have a simple React app that tracks the mouse position and displays it on the page. The following is an example of how you might have built it:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/af8d90f98eaf98a5269cae60f4f4fc07/href">https://medium.com/media/af8d90f98eaf98a5269cae60f4f4fc07/href</a></iframe><p>Now, let’s imagine that we want to track the mouse position in another component as well. Can we reuse any of the code from our &lt;App&gt;?</p><p>In the createClass paradigm, the problem of code reuse was solved using a technique called “mixins”. Let’s create a MouseMixin that anyone can use to track the mouse position.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/84281415b815b1f2f9fb264db47ef6cd/href">https://medium.com/media/84281415b815b1f2f9fb264db47ef6cd/href</a></iframe><p>Problem solved, right?! Now anyone can simply “mix in” MouseMixin to their component class to get the x and y of the mouse in this.state!</p><h3>HOCs Are the New Mixins</h3><p>Then last year, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">ES6 classes</a> arrived and ultimately the React team decided to move away from using createClass to use them instead. It was a wise decision. Who wants to maintain their own class model when JavaScript already has one built-in?</p><p>But there was a problem: <strong>ES6 classes don’t support mixins</strong>. Also, besides the fact they aren’t part of the ES6 class spec, mixins have other shortcomings too, many of which <a href="https://medium.com/u/a3a8af6addc1">Dan</a> discussed at length in <a href="https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html">a post on the React blog</a>.</p><p>To summarize, problems with mixins are:</p><ul><li><strong>ES6 classes</strong>. They don’t support mixins.</li><li><strong>Indirection</strong>. Mixins that modify state make it tricky to tell where that state is coming from, especially when there’s more than one mixin.</li><li><strong>Naming collisions</strong>. Two mixins that try to update the same piece of state may overwrite one another. The createClass API included a check that would warn you if two mixins had a getInitialState value with the same keys, but it wasn’t airtight.</li></ul><p>So instead of using mixins, many in the React community eventually settled on an alternative technique for code reuse known as <a href="https://facebook.github.io/react/docs/higher-order-components.html">higher-order components</a>, or HOCs. In this paradigm, code is shared using a similar technique to <a href="https://en.wikipedia.org/wiki/Decorator_pattern"><strong>decorators</strong></a>; you start with the component that defines the bulk of the markup to be rendered and then wrap it in more components that contain the behavior you’d like to share. Instead of <em>mixing in</em> the behavior you need, you can just <em>decorate</em> your component! 😎</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f3743e6894df4b686b5c4142911b34e5/href">https://medium.com/media/f3743e6894df4b686b5c4142911b34e5/href</a></iframe><p>It was a good solution that solved the problem of code reuse elegantly in the brave new world of ES6 classes, and the community adopted it in droves.</p><p>At this point I’d like to stop and ask: what did we gain by moving to higher-order components? Did we solve any of the problems we had with mixins?</p><p>Let’s see:</p><ul><li><strong>ES6 classes</strong>. Yep! No problems here. We can use HOCs with components created using ES6 classes.</li><li><strong>Indirection</strong>. We still have the same problem with indirection that we had when we were using mixins. Except this time instead of wondering where our state comes from we’re wondering which HOC provides which props.</li><li><strong>Naming collisions</strong>. Unfortunately we still have this problem too. Two HOCs that try to use the same prop name will collide and overwrite one another, except this time it’s slightly more insidious because React won’t warn us about the prop name collision. 😳</li></ul><p>Another problem that both mixins and HOCs share is that they use <strong>static composition</strong> instead of <strong>dynamic composition</strong>. Ask yourself: where is the composition happening in the HOC paradigm? Static composition happens once, when the component class is created (e.g. AppWithMouse in the previous example).</p><p>You don’t use mixins or HOCs in your render method, which is a key piece of React’s <strong>dynamic</strong> composition model. When you compose in render, you get to take advantage of the full React lifecycle. This point is subtle, and probably deserves its own blog post at some point in the future, but I digress. 😅</p><p>So in summary: <strong>using a HOC with ES6 classes poses many of the same problems that mixins did with </strong><strong>createClass, just re-arranged a bit</strong>.</p><p>Welcome to the new mixins! 🤗</p><p>In addition to these drawbacks, <strong>HOCs introduce a lot of ceremony</strong> due to the fact that they <em>wrap</em> components and create new ones<em> </em>instead of being <em>mixed in</em> to existing components. The component that is returned from the HOC needs to act as similarly as it can to the component that it wraps (it should take the same props, etc.) This fact alone requires a lot of boilerplate code just to build a robust HOC.</p><p>You can see a good example of what I’m talking about in <a href="https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/withRouter.js">the </a><a href="https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/withRouter.js">withRouter HOC</a> that ships with <a href="https://github.com/ReactTraining/react-router">React Router</a>. The <a href="https://github.com/ReactTraining/react-router/blob/f77440ec9025d463c6713039ab1a6db1faca99bb/packages/react-router/modules/withRouter.js#L14">prop passing</a>, the <a href="https://github.com/ReactTraining/react-router/blob/f77440ec9025d463c6713039ab1a6db1faca99bb/packages/react-router/modules/withRouter.js#L22">wrappedComponentRef</a>, the <a href="https://github.com/ReactTraining/react-router/blob/f77440ec9025d463c6713039ab1a6db1faca99bb/packages/react-router/modules/withRouter.js#L25">hoisting of the wrapped component’s static properties</a>, and other things are all part of the dance you need to do if you’re going to ship a HOC with your React library.</p><h3>Render Props</h3><p>There is another technique for sharing code that avoids the drawbacks of mixins and HOCs. At <a href="https://reacttraining.com/">React Training</a>, we call this technique “Render Props”.</p><p>The first time I ever saw a render prop was in <a href="https://medium.com/u/701b0000d771">Cheng Lou</a>’s <a href="https://www.youtube.com/watch?v=1tavDv5hXpo">talk on react-motion</a> at React Europe where he talked about the &lt;Motion children&gt; API that they were using to share interpolated animation values with the parent component. If I had to try and define it, I’d say something like this:</p><blockquote>A render prop is a function prop that a component uses to know what to render.</blockquote><p>More generally speaking, the idea is this: instead of “mixing in” or decorating a component to share behavior, <strong>just render a regular component with a function prop that it can use to share some state with you</strong>.</p><p>Continuing with the example above, we can simplify the withMouse HOC to a regular &lt;Mouse&gt; component with a render prop that is a function. Then, inside &lt;Mouse&gt;&#39;s render, we can use that prop to know what to render!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/170a0bec8d91ae3eb57ead6fd4397af0/href">https://medium.com/media/170a0bec8d91ae3eb57ead6fd4397af0/href</a></iframe><p>The main concept to understand here is that the &lt;Mouse&gt; component essentially exposes its state to the &lt;App&gt; component by calling its render prop. Therefore, &lt;App&gt; can render whatever it wants with that state. Pretty cool. 😎</p><p>I should clarify at this point that “children as a function” is <em>the exact same concept</em>, just using the children prop instead of render. When I say “render prop” I’m not talking specifically about a prop <em>named</em> render, but rather the concept of having a prop that you use to render something. 😅</p><p>This technique avoids all of the problems we had with mixins and HOCs:</p><ul><li><strong>ES6 classes</strong>. Yep, not a problem. We can use render props with components that are created using ES6 classes.</li><li><strong>Indirection</strong>. We don’t have to wonder where our state or props are coming from. We can see them in the render prop’s argument list.</li><li><strong>Naming collisions</strong>. There is no automatic merging of property names, so there is no chance for a naming collision.</li></ul><p>And there’s absolutely <strong>no ceremony</strong> required to use a render prop because you’re not <em>wrapping</em> or <em>decorating</em> some other component. It’s just a function! Actually, if you’re using <a href="https://www.typescriptlang.org/">TypeScript</a> or <a href="https://flow.org/">Flow</a>, you’ll probably find it much easier to write a type definition for your component with a render prop than its equivalent HOC. Again, a topic for a separate post!</p><p>Additionally, <strong>the composition model here is <em>dynamic</em></strong>! Everything happens inside of render, so we get to take full advantage of the React lifecycle and the natural flow of props &amp; state.</p><p>Using this pattern, you can replace <strong>any</strong> HOC with a regular component with a render prop. And we can prove it, too! 😅</p><h3>Render Props &gt; HOCs</h3><p>One of the most convincing pieces of evidence that render props are a more powerful pattern than HOCs is the fact that any HOC can be implemented using a render prop, but the inverse is not true. The following is an implementation of our withMouse HOC using a regular ol’ &lt;Mouse&gt;:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ec65d8f7090e47747dbd3eb4072f89ce/href">https://medium.com/media/ec65d8f7090e47747dbd3eb4072f89ce/href</a></iframe><p>Observant readers may have already noticed that the withRouter HOC in the React Router codebase is actually implemented with … wait for it … <a href="https://github.com/ReactTraining/react-router/blob/f77440ec9025d463c6713039ab1a6db1faca99bb/packages/react-router/modules/withRouter.js#L13">a render prop</a>!</p><p>So go ahead, try out render props in your codebase! Go and find some HOC and turn it into a regular component with a render prop. As you do, you should see a lot of the HOC ceremony code melt away and you’ll start to take better advantage of the dynamic composition model that React gives us, which is extremely cool. 😎</p><p><a href="https://twitter.com/mjackson"><em>Michael</em></a><em> is a partner at </em><a href="https://reacttraining.com/"><em>React Training</em></a><em> and a prolific </em><a href="https://github.com/mjackson"><em>OSS contributor</em></a><em> in the React community. To learn more about upcoming training workshops and courses, please </em><a href="http://reacttraining.us16.list-manage1.com/subscribe?u=47df8ab2101d1dd83353427fc&amp;id=83f54bda60"><em>subscribe to the mailing list</em></a><em> and follow </em><a href="https://twitter.com/reacttraining"><em>React Training on Twitter</em></a><em>.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=50de598f11ce" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hello, depression.]]></title>
            <link>https://medium.com/@mjackson/hello-depression-c2f09389d3c?source=rss-7f9567e0d71c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c2f09389d3c</guid>
            <category><![CDATA[mental-health]]></category>
            <category><![CDATA[depression]]></category>
            <dc:creator><![CDATA[Michael Jackson]]></dc:creator>
            <pubDate>Sun, 20 Aug 2017 06:39:26 GMT</pubDate>
            <atom:updated>2017-08-26T14:46:15.771Z</atom:updated>
            <content:encoded><![CDATA[<p>Hello, depression.</p><p>You know I hate you. How many times do I have to tell you? It’s getting old. Heck, it was old about a decade ago.</p><p>I’ve tried so hard to get rid of you! For years I thought I could just ignore you. That you’d go away on your own. That I’d grow out of you. That I could just exercise harder or eat better or pray longer and you’d get the hint and move on.</p><p>But alas, here we are again.</p><p>And you know, I think I’m starting to figure you out. After spending so much time with you over the past 20 years, I’m beginning to wonder if you’ll ever go away. So I’d better learn to deal with you. It’s either that or you’ll keep chipping away, trying to destroy me and everything I love.</p><p>The first thing I’ve learned about you is that you’re a phony. You are not an emotion. You, depression, are the lack of emotion. I used to mistake you for sadness, but I can see now that you’re different.</p><p>I can deal with sadness. Sadness is a natural feeling I get when my heart aches, usually when I miss someone. Without sadness, I’d have a hard time understanding what it truly means to be happy. But, depression, you don’t teach me anything about happiness. You are a numbness; a void. So I’m sorry to break it to you, but even sadness is better than you.</p><p>The second thing I’ve learned about you is that I did nothing wrong to deserve you. You aren’t the punishment for some misdeed. You’re a biological condition; a struggle of the mind.</p><p>I used to wonder what I needed to change in my life so that I’d make sure I never saw you again. What was I doing wrong? Maybe if I made more money or changed jobs or moved to a different place I could finally be free. Now I know that you are not the result of my circumstances. I view my struggle with you like any other workout. It’s going to take lots of time and dedication to put you in your place.</p><p>The third thing I’ve learned is that I have the power to choose my attitude. I always do, despite what you say. You and I have been face to face so many times, and lots of times you’ve convinced me that I can’t change; that I need to remain in my detached, numb, depressed state for a while longer and let it all just play out.</p><p>But you’re wrong. Even when you’re around I can choose to respond positively to the world around me. Even when I am depressed, it’s still my choice to do the things I do and say the things I say.</p><p>Because I choose to feel.</p><p>You see, I’ve got people who are counting on me, people who I love, and I refuse to just let them down.</p><p>When my son calls me late at night 20 years from now, I’m going to be there for him. He’ll probably call because, as a young father, he’s going to feel the weight of caring for his family. And that weight might tip the scales a little in his mind and open the door for you to sneak into his life too. And he’s going to need to talk to someone who can help him learn to feel again; to reject the numbness and start to learn some of the same things I’ve been learning about you and, more importantly, about himself. I’m sure as hell not going to just leave him to figure all this out on his own, the way I’ve had to.</p><p>So anyway, I just thought I’d set the record straight with you. Since you seem to like to stick around, you should at least know how I feel.</p><p>And I will always choose to feel.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c2f09389d3c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Universal JavaScript]]></title>
            <link>https://medium.com/@mjackson/universal-javascript-4761051b7ae9?source=rss-7f9567e0d71c------2</link>
            <guid isPermaLink="false">https://medium.com/p/4761051b7ae9</guid>
            <dc:creator><![CDATA[Michael Jackson]]></dc:creator>
            <pubDate>Mon, 08 Jun 2015 16:43:51 GMT</pubDate>
            <atom:updated>2015-06-08T20:39:14.882Z</atom:updated>
            <content:encoded><![CDATA[<p>In the beginning, there was Netscape. And Netscape wanted to run Scheme in Netscape Navigator. So they hired Brendan Eich to work on it. But then they changed their minds and decided they wanted Java instead. And lo, JavaScript was born. And it was good (enough).</p><p>Some years later, Ryan Dahl had this crazy idea to pair Google’s V8 JavaScript runtime with libev so developers would have a way to run their JavaScript outside the browser. And node.js became a thing. And npm. And the people rejoiced.</p><p>And people started writing web servers in JavaScript, and flying helicopters with JavaScript, and putting it on tablets and mobile phones, and embedding it in thermostats and refrigerators and pretty much anywhere they pleased. And there was a proliferation of JavaScript. And Serious Developers™ despised the common people who wrote JavaScript, but the people just kept writing more and more JavaScript.</p><p>And the people sought for a word to describe this widespread adoption of JavaScript, because the term “JavaScript” on its own was not sufficient to describe its vastness. So <a href="http://blog.nodejitsu.com/scaling-isomorphic-javascript-code/">Charlie Robbins suggested</a> that the term “Isomorphic JavaScript” might be used to describe JavaScript code that “can execute both on the client and the server”. And nobody knew what the hell it meant, but now instead of just writing JavaScript the people were writing Isomorphic JavaScript.</p><p>Wait … huh?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/317/1*kPfi8tw6n_RgmSd_WWrlfA.png" /></figure><p>When coining the term <em>Isomorphic JavaScript</em>, Robbins explains that he meant “that any given line of code (with notable exceptions) can execute both on the client and the server”. However, if we examine more closely the meaning of the word <em>isomorphic</em> we read “corresponding or similar in form and relations”. In other words, two entities that <em>are not the same </em>but only <em>look the same</em>. This would be a great word to use when describing the relationship between <a href="http://jquery.com/">jQuery</a> and <a href="http://zeptojs.com/">Zepto</a> or <a href="http://underscorejs.org/">Underscore</a> and <a href="https://lodash.com/">lodash</a>, for example. These libraries are similar in form (they share the same API) but differ in underlying ideas and philosophy.</p><p>Instead, what we need is a word that describes <em>the same code</em> but <em>running in a different environment</em>. Nowadays we run JavaScript code not only on servers and in browsers, but on mobile and embedded devices as well. We’re running it on Raspberry Pis and Wii Us and <a href="https://github.com/facebook/react-native">iPhones</a>. But this is a purely technical argument. What’s even more important is conveying <em>understanding</em>.</p><p>But of course, understanding is highly subjective. Recently, Ryan Florence and I began conducting <a href="https://reactjs-training.com/">React.js Training</a> courses full-time. Up to this point we have trained several hundred developers, and it’s not uncommon for someone to ask what the word <em>isomorphic</em> means. Now, this is purely anecdotal evidence, but when we use the word <em>universal</em> instead of <em>isomorphic</em> <a href="https://github.com/facebook/react/pull/4041#issuecomment-109420008">everyone gets it</a>. It may have something to do with <a href="http://en.wikipedia.org/wiki/Universal_binary">Apple using that same word</a> to describe application bundles that ran on both architectures back when they made the switch from PowerPC to Intel.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/526/1*pkA5znpcqqmIwZRXesioGA.png" /></figure><p>It’s true that <a href="http://martinfowler.com/bliki/TwoHardThings.html">there are two hard problems in computer science</a> and one of them is <em>naming things</em>. Why? Because <strong>good names are important</strong>. A good name teaches about purpose and responsibility, so you have to spend some time thinking about it.</p><p>So let’s give our JavaScript code a name that people can understand; a name that indicates what it actually does instead of introducing words into the common vernacular that clearly don’t belong there; a name that teaches people that it runs not only on servers and browsers, but on native devices and embedded architectures as well.</p><p>Let’s call it <a href="https://github.com/facebook/react/pull/4041"><strong>Universal JavaScript</strong></a>.</p><p><em>My thanks to </em><a href="https://twitter.com/ryanflorence"><em>Ryan Florence</em></a><em>, </em><a href="https://twitter.com/floydophone"><em>Pete Hunt</em></a><em>, </em><a href="https://twitter.com/peterc"><em>Peter Cooper</em></a><em>, </em><a href="https://twitter.com/dan_abramov"><em>Dan Abramov</em></a><em>, and </em><a href="https://twitter.com/markdalgleish"><em>Mark Dalgleish</em></a><em> for reviewing this post prior to publication. Also, thanks to Ryan for riffing on these ideas with me.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4761051b7ae9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>