<?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>Forem: Kel</title>
    <description>The latest articles on Forem by Kel (@kellenpiffner).</description>
    <link>https://forem.com/kellenpiffner</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%2F214934%2F166b9855-fdcd-487d-b51b-86769eb3185c.jpg</url>
      <title>Forem: Kel</title>
      <link>https://forem.com/kellenpiffner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kellenpiffner"/>
    <language>en</language>
    <item>
      <title>Safety and Confidence</title>
      <dc:creator>Kel</dc:creator>
      <pubDate>Wed, 01 Jan 2020 18:00:00 +0000</pubDate>
      <link>https://forem.com/kellenpiffner/safety-and-confidence-h1o</link>
      <guid>https://forem.com/kellenpiffner/safety-and-confidence-h1o</guid>
      <description>&lt;p&gt;As employers we want confident employees. We want people who can get things done with as little supervision as possible. We want to give them money and in exchange they give us value from their effort.&lt;/p&gt;

&lt;p&gt;And yet, that's not what usually happens. People require a lot of supervision, they aren't motivated. So why not? Why &lt;em&gt;aren't&lt;/em&gt; all your employees rock stars?&lt;/p&gt;

&lt;h2&gt;
  
  
  Fear
&lt;/h2&gt;

&lt;p&gt;It starts with fear. What are your employees afraid of?&lt;/p&gt;

&lt;p&gt;Here's an example: Imagine a meeting, someone speaks up and says something ignorant. They don't fully understand the implications of what was going on, say something, and look foolish. At &lt;em&gt;best&lt;/em&gt;, people will laugh, shaming them. At worst, someone might yell at them. It could result in them getting a bad review. It could result in them getting fired.&lt;/p&gt;

&lt;p&gt;We decide whether risks are "worth it" by weighing the possible rewards against the possible consequences. Your employees are weighing getting the job done against the possibility of getting fired. If they take the "safe" path, and stay quiet, they'll get the job done slower, and run less risk of getting fired. If they're &lt;em&gt;less efficient&lt;/em&gt;, they're safer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety
&lt;/h2&gt;

&lt;p&gt;On the &lt;a href="https://gettingappsdone.com/"&gt;Getting Apps Done&lt;/a&gt; podcast, we talk about safety in the workplace quite a bit, but it's worth describing again here: "Safety" in this context means that even if you take a risk and it fails, the consequences won't harm you. You will not lose your job, you will not be shamed, you will continue to have food and shelter and people in your life.&lt;/p&gt;

&lt;p&gt;Individuals can take actions to increase their safety. The most straight forward is saving money. It's less risky to take chances at work if you can afford to be laid off and find another job.&lt;/p&gt;

&lt;p&gt;But there are things we can do as employers too. Talk to your employees about the risks they &lt;em&gt;could&lt;/em&gt; take. Discuss the consequences of those risks and see if there are ways to mitigate them.&lt;/p&gt;

&lt;p&gt;A complex example might be a customer project where a mistake could throw off the timeline. The further out the timeline is, the more likely something will go wrong. A timeline should have a buffer for failure. The more experienced you get as developers, as managers, as leaders, the closer to that edge you can get. You'll know the most likely risks and how to plan for them and the less buffer will be required.&lt;/p&gt;

&lt;p&gt;This is the whole purpose of Agile! It goes on the assumption that you're going to mess up and that iterating the plan will be required. Over time your metrics about work estimates get more accurate and you can plan better. Agile creates a safety net on failure by making sure each piece of work is "bite sized" and requesting regular feedback to verify that the work completed matches what was expected. Maybe you messed up an individual ticket, or maybe a sprint. But it's &lt;em&gt;unlikely&lt;/em&gt; the entire project would be considered a failure if you've been getting constant feedback.&lt;/p&gt;

&lt;p&gt;We apply this strategy of limiting consequences to timelines, projects, and processes, but it's rare that it's applied directly to people.&lt;/p&gt;

&lt;p&gt;In the earlier example of a meeting: Make it clear that ignorance is fine! People are so trained to be &lt;em&gt;afraid&lt;/em&gt; of showing their ignorance that they often won't ask questions when they don't understand something. Make it clear that asking questions is a safe thing to do, and even an expected thing to do.&lt;/p&gt;

&lt;p&gt;Make it &lt;em&gt;safe&lt;/em&gt; for your employees to fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust, Responsibility, Consent, Confidence
&lt;/h2&gt;

&lt;p&gt;When you discuss risks with your team, ask them questions until you understand their viewpoints, and most importantly, trust what they tell you. They're going to be wrong sometimes and that's OK! In exchange for your trust, they consent to being responsible for what they agreed to.&lt;/p&gt;

&lt;p&gt;This is where a lot of organizations break down. Consent to responsibility has to be voluntary, because otherwise it's not consent! If you threaten them you're not trusting them, you're forcing them, you're coercing them.&lt;/p&gt;

&lt;p&gt;For many, the idea of being responsible for your own actions is just assumed, but the first example in this article points out that sticking your head out can impact someone's safety and their family's. We can't perfectly predict the future, and being responsible for something's outcome is always a gamble. If taking on that responsibility is required by your team, ask them what it would take for them to agree to it. Support them with safety.&lt;/p&gt;

&lt;p&gt;Let's go back to that timeline example. You ask the team how long it will take and they say 10 weeks. You list out the possible failure points, and make plans for the most likely, or the ones with the most impactful consequences. And then you do it. And if it goes great or it bombs, responsibility is what people agreed to. Everyone will make mistakes and instead of trying to bury or hide from them, they'll learn from them.&lt;/p&gt;

&lt;p&gt;Learning from your mistakes is the road to confidence. The more you know you can safely handle the more confident you are in your own ability. By creating an environment that's safe, people can learn that confidence by making mistakes over and over again, and if they're responsible for their own actions, then they'll have pressure to avoid that as much as possible. They can make decisions based on actual risk instead of "risk of getting yelled at by the boss".&lt;/p&gt;

&lt;h2&gt;
  
  
  Do the Impossible
&lt;/h2&gt;

&lt;p&gt;Having a perfectly safe environment is impossible, but what you can do is lower the possibility of dangerous consequences. You can do this by making an environment that's consensual, that's safe, and where people are free to do the work they want to do to the best of their ability.&lt;/p&gt;

&lt;p&gt;You can create an environment of trust, where you as an employer trust your employees to succeed &lt;em&gt;and&lt;/em&gt; fail. When you let people fail and pull themselves back up again, you teach them confidence in their own abilities.&lt;/p&gt;

&lt;p&gt;Help them all be rock stars.&lt;/p&gt;

&lt;p&gt;-Kel&lt;/p&gt;

</description>
      <category>agile</category>
      <category>leadership</category>
      <category>motivation</category>
      <category>management</category>
    </item>
    <item>
      <title>Compromise and Test</title>
      <dc:creator>Kel</dc:creator>
      <pubDate>Mon, 12 Nov 2018 17:41:03 +0000</pubDate>
      <link>https://forem.com/gettingappsdone/compromise-and-test-3852</link>
      <guid>https://forem.com/gettingappsdone/compromise-and-test-3852</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uu0xP8T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/compromise-and-test/rawpixel-669602-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uu0xP8T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/compromise-and-test/rawpixel-669602-unsplash.jpg" alt="Person gesturing at laptop" title="Let's argue about computer things"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;
&lt;a href="https://unsplash.com/@rawpixel?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by rawpixel on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;p&gt;In my &lt;a href="https://dev.to/gettingappsdone/the-choice-of-priorities-53kf"&gt;previous post&lt;/a&gt; I talked about what to do when presented with a question of priorities. I argue that the answer is to do "both". But what about when those two priorities are mutually exclusive? "Do we make the button green or orange?" You can't really do both in this case, right?&lt;/p&gt;

&lt;p&gt;When two people disagree on a choice like this, it often means there's a fundamental difference in understanding of the topic itself. Maybe they 'weigh' the priorities differently. In the example of "green" vs. "orange", maybe they're really arguing "positive" vs. "bright".&lt;/p&gt;

&lt;p&gt;The first step in any disagreement is to get people talking it through. With luck, they can work it out just by sharing their own understandings of the subject. But fairly often the opinions will be strongly held, and difficult to change. So then what?&lt;/p&gt;

&lt;p&gt;The answer is exactly the same as the question priorities: &lt;strong&gt;Do them both.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, it's not a question of difficulty, but of cost. Doing them both costs twice as much, but often will lead to a better overall solution. This is the same idea behind &lt;a href="https://en.wikipedia.org/wiki/A/B_testing"&gt;A/B testing&lt;/a&gt; where you put both options out there and let the data decide.&lt;/p&gt;

&lt;p&gt;Even for simpler things, where 'common sense' dictates one is probably better than the other, data (or customer feedback) can often reveal completely different understandings.&lt;/p&gt;

&lt;p&gt;And beyond ending up with a better solution, this is another way to get arguing team members to compromise and work together, which is almost always more valuable than getting a button color just right.&lt;/p&gt;

</description>
      <category>agile</category>
      <category>management</category>
    </item>
    <item>
      <title>The Choice of Priorities</title>
      <dc:creator>Kel</dc:creator>
      <pubDate>Mon, 22 Oct 2018 21:17:40 +0000</pubDate>
      <link>https://forem.com/gettingappsdone/the-choice-of-priorities-53kf</link>
      <guid>https://forem.com/gettingappsdone/the-choice-of-priorities-53kf</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e4ZfWlmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/choice-of-priorities/brendan-church-182747-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e4ZfWlmR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/choice-of-priorities/brendan-church-182747-unsplash.jpg" alt="A sign post with two one way street signs" title="Which way?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;
&lt;a href="https://unsplash.com/@bdchu614?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by Brendan Church on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;p&gt;Recently my daily feed was filled with a discussion about "What's more important? Writing maintainable software, or shipping software?"&lt;/p&gt;

&lt;p&gt;There was a lot of back and forth about code quality, technical debt, not being able to sell something that isn't complete, and all the other points you would expect in this type of argument.&lt;/p&gt;

&lt;p&gt;In the end, I'm pretty sure "shippability" was "winning", but I want to make a different point: The fact that you're having an argument about it, that many people have strong opinions on both sides, means that &lt;em&gt;both&lt;/em&gt; are important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do them both.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, that's more difficult. But that's how you get better, and it's why people pay more for experienced developers.&lt;/p&gt;

&lt;p&gt;(If you're new, though, definitely just get something done and make it better over time. "Don't let perfect get in the way of good enough.")&lt;/p&gt;

</description>
      <category>agile</category>
      <category>production</category>
      <category>management</category>
    </item>
    <item>
      <title>Your interview questions are awful (but we can fix them)</title>
      <dc:creator>Kel</dc:creator>
      <pubDate>Wed, 17 Oct 2018 17:17:16 +0000</pubDate>
      <link>https://forem.com/gettingappsdone/your-interview-questions-are-awful-but-we-can-fix-them-2oj5</link>
      <guid>https://forem.com/gettingappsdone/your-interview-questions-are-awful-but-we-can-fix-them-2oj5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--03lYRv2A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/branko-stancevic-417172-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--03lYRv2A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/branko-stancevic-417172-unsplash.jpg" alt="Screenshot showing programming skills" title="Programming Skills"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;
&lt;a href="https://unsplash.com/@bdchu614?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by Brendan Church on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;p&gt;The first time I was involved in a technical interview I was asked to present and grade a coding question: "What does this script do?" The candidate was then handed a print out of a (relatively) simple &lt;a href="https://en.wikipedia.org/wiki/VBScript"&gt;VBScript&lt;/a&gt; that changed the computer name of a Windows PC.&lt;/p&gt;

&lt;p&gt;Only one candidate answered correctly. Every other candidate failed the question with an "I don't know."&lt;/p&gt;

&lt;p&gt;On first glance, this seems a reasonable question. Part of the job they were interviewing for often required working with scripts to deploy computers and software. I told them that we weren't looking for a specific answer, just a general idea of "What does this do?" The candidate failing to even make a guess seems like an interview fail. They couldn't think on their feet. They couldn't think creatively.&lt;/p&gt;

&lt;p&gt;But was it really a failure of the interviewee?&lt;/p&gt;

&lt;p&gt;As a test, we handed out that same question to a few of non-technical folks in the office. All of them answered correctly within a minute of skimming it by looking at method and variable names and guessing.&lt;/p&gt;

&lt;p&gt;It's been a long time and many interviews since those first ones and I now look at their failure to respond as a failure on my part as the interviewer. If a non-technical person could answer the question correctly, most of these candidates should have gotten it right, too. So why didn't they? Why did they only answer with a "I don't know?"&lt;/p&gt;

&lt;h1&gt;
  
  
  Fear
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--732kgNTQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/ben-white-292680-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--732kgNTQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/ben-white-292680-unsplash.jpg" alt="Person sitting contemplating" title="Nerves"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;
&lt;a href="https://unsplash.com/@benwhitephotography?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by Ben White on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;p&gt;Job interviews are scary. Unless they don't need the job, there's real risk involved in failing an interview. Paying bills, making rent, supporting a family, growing their career in a direction that really excites them. The more they want or need the job, the more that fear is present with them in an interview.&lt;/p&gt;

&lt;p&gt;An important part of an interviewer's job is to help them relax. You're not going to learn the full range of their skills if they're too nervous to answer your questions. The easiest way to help a candidate relax is to help remove their fear of failing. You can do this surprisingly simply: Ask them more questions that they're going to fail.&lt;/p&gt;

&lt;p&gt;It seems backwards, right? But the goal here isn't to catch them in a trap, but to show them that answering a question incorrectly is &lt;em&gt;safe&lt;/em&gt; to do. Dig into their wrong answers, see how they got there. Ask similar questions to see if they know related information. If they look nervous, tell them it's &lt;em&gt;ok&lt;/em&gt; to not know the answer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some people think interviews should test for "handling stressful situations". Unless your business is in high stress situations (think: disaster relief operations), then this is bullshit. It's your job as an employer to provide a safe place to get work done.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Part of what you have to do to measure a candidates full skill is prove to them that you're not going to judge them arbitrarily. Prove to them that one wrong answer will not keep them from getting a chance at a job.&lt;/p&gt;

&lt;p&gt;So what should I have done differently? I was on the right track, reassuring them that guesses were fine, but I didn't go far enough in helping them relax or preparing them to answer. And part of that was due to the specificity of the question itself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Digging into a skill
&lt;/h1&gt;

&lt;p&gt;When you have a question with a specific answer you create a very obvious point where the candidate can fail. They know getting the job relies strongly on the correct answer, and that fear of failure will be eating up most of their thoughts.&lt;/p&gt;

&lt;p&gt;To help mitigate this, you ask lots of questions. Think about it like this: Would you prefer one chance, 0% or 100%, on passing a test, or 10 chances, where it's possible to get a 70% passing grade?&lt;/p&gt;

&lt;p&gt;In the example of the computer rename script, the skill I was looking for was "The ability to work with scripts". Preferably creating and editing, but just being able to read them to see if it "did what you want" would have been fine.&lt;/p&gt;

&lt;p&gt;A better question: "Have you ever used a script to automate a task before?"&lt;/p&gt;

&lt;p&gt;"But wait!" you say. "That answer isn't measurable! How do I know if they got it right?!" Answer: You ask more questions.&lt;/p&gt;

&lt;p&gt;For example: If the candidate said yes, ask them about the time they used it. Ask them about what it did, how many computers it ran on. Ask them where they found the script, and how they knew what it did.&lt;/p&gt;

&lt;p&gt;Even if they said no, they still haven't necessarily failed. Ask them if they think they could "figure it out." (I've yet to interview a technical job candidate who wasn't confident they could figure something out that they didn't know given time and google). Now do the handout. The handout in our interview was an actual script we used daily. It was an accurate representation of the job. &lt;em&gt;Tell them that&lt;/em&gt;. It gives them incentive to really try figuring it out since it's the job they &lt;em&gt;want&lt;/em&gt; to do. For an even more accurate job representation, hand them a laptop with Google ready. Letting someone know that you won't arbitrarily limit their tools to get a job done does wonders for relaxing them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4qPjClbV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/rawpixel-423656-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4qPjClbV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/rawpixel-423656-unsplash.jpg" alt="Person with beard being interviewed at a laptop" title="By the power of your beard, Google the answer"&gt;&lt;/a&gt;&lt;/p&gt;

By the power of your beard and Google, figure out the answer. 
&lt;cite&gt;
&lt;a href="https://unsplash.com/@rawpixel?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by rawpixel on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;h1&gt;
  
  
  Measuring a skill
&lt;/h1&gt;

&lt;p&gt;After reading the above, you're probably thinking "But that question sounds too easy with all that help". You're right! And isn't that great? Think about how many candidates could show that they could &lt;em&gt;really do the job&lt;/em&gt;. We just went from one, to (likely) all of them.&lt;/p&gt;

&lt;p&gt;On top of that, if you went down the first question path, you know how deep their scripting skills go. You can &lt;em&gt;measure&lt;/em&gt; it relative to your own skill. Are they better at scripting than you? Worse? Maybe they've written lots of scripts, but in different areas than yours. Write that down. Those are all important impressions to use when comparing candidates against each other.&lt;/p&gt;

&lt;p&gt;Before you begin an interview, you should have a list of specific skills you're looking for and a list of open ended questions that can help candidates tell you about times they've used those skills.&lt;/p&gt;

&lt;p&gt;Once you have that list, talk to them until you can answer these questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do they know more than you?&lt;/li&gt;
&lt;li&gt;Do they know less? How long would it take you to train them to a level of competence needed to do the job?&lt;/li&gt;
&lt;li&gt;Do they have other, similar skills to make up for not knowing this specific skill? How deep does &lt;em&gt;that&lt;/em&gt; skill go?&lt;/li&gt;
&lt;li&gt;How &lt;em&gt;excited&lt;/em&gt; are they about the skill. Is it an interest? Something they hate but do anyway?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A helpful "trick" for getting to the depth of a candidates skill is to tell them exactly what you're looking for! They'll be eager to show you that they can do it, or to show you skills similar to what you're looking for.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep in mind the real question you're trying to answer: &lt;em&gt;Do they have the skill and desire necessary to do the job?&lt;/em&gt; If you can't confidently say 'yes' or 'no', keep digging, keep asking questions. I really can't stress this enough. This is important. You're in a position of authority - in a position to approve or deny them livelihood. If you reject someone for a position, you should be prepared to explain the reasons why for your choice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I've found it common that interviewers don't feel confident enough in their own abilities to judge someone else. Two things to keep in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You're measuring their skill &lt;em&gt;relative&lt;/em&gt; to yours. You don't need to know everything about a subject to do that.&lt;/li&gt;
&lt;li&gt;Someone, likely your manager, thought you were qualified because you had the skills they're looking for. You can do this.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you really aren't qualified, though, make sure someone else in the room is. (For example: back when I gave that first interview, you wouldn't have wanted me to grade someone's diplomatic skills.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Comparing candidates
&lt;/h1&gt;

&lt;p&gt;Once you have the relative skill of candidates, it's pretty straightforward to compare them. Once again, though, you should be able to confidently describe why one candidate is better than another. Use specific terms. In a perfect world, you would be able to coach a failed candidate explaining the things they should work on.&lt;/p&gt;

&lt;p&gt;Also, you should have multiple people performing these skill measurements, and the people doing those measurements should have the skill level you're looking for. (There's no real point in having your worst communicator interviewing someone about their email skills.)&lt;/p&gt;

&lt;p&gt;One other thing to keep in mind: Sometimes a candidate comes along with a great set of skills that doesn't neatly fit into any one role. If you can make it work in your organization, these people make &lt;em&gt;great&lt;/em&gt; employees. The diversity of those skills can lead to innovative solutions to difficult problems. When you can: fit roles to people, not people to roles.&lt;/p&gt;

&lt;h1&gt;
  
  
  Iterating your process
&lt;/h1&gt;

&lt;p&gt;A lot of my opinions on interviews formed after my boss handed me a stack of developer resumes and told me I had 30 minutes to screen each of them for the necessary tech skills. Three or four interviews a day, generally given back to back, for a couple weeks.&lt;/p&gt;

&lt;p&gt;During that time, I iterated. I wrote down which questions worked well to draw out a candidates skills and which ones didn't. Most of the time I could confidently tell within those 30 minutes whether they had what we wanted or not. And, if I wasn't confident, I passed them on anyway. I didn't want my gut 'feeling' to be the deciding factor on someone's employment.&lt;/p&gt;

&lt;p&gt;But I was mostly surprised at how effective this method was. At the end of every interview, I could accurately communicate their skills relative to mine to my manager so he knew which ones to interview next, and I could repeat the results of the process with the next candidate.&lt;/p&gt;

&lt;p&gt;Iteration is always important. Something I've learned relatively recently is to keep metrics at each 'stage' of an interview process. Every stage acts like a 'filter'. They're an arbitrary line in the sand that candidates have to make it across. "The top 10 candidates". It's important to know where people fall out and if great candidates are falling through. If you see a problem, fix it and try again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some additional reading on the subject: &lt;a href="https://medium.com/make-better-software/we-re-bad-at-interviewing-developers-and-how-to-fix-it-e02c834dc1d7"&gt;We’re Bad at Interviewing Developers (and How to Fix It)&lt;/a&gt;. (I swear I didn't intentionally pick the same title. Great minds think alike?)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion - Interviews vs. Tests
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hkMklD1e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/rawpixel-1046277-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hkMklD1e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/bad-interview-questions/rawpixel-1046277-unsplash.jpg" alt="Two hands shaking" title="Another successful handshake"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;
&lt;a href="https://unsplash.com/@rawpixel?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Photo by rawpixel on Unsplash&lt;/a&gt;
&lt;/cite&gt;




&lt;p&gt;Finally, I'm not Google or Facebook. When you start hiring on that scale, you need more specific metrics to be able to assure relative consistency of skills. Those types of questions have become the 'standardized testing' of jobs.&lt;/p&gt;

&lt;p&gt;If you're not hiring on that scale, then you likely just want more developers like the ones you have. Let them interview and make good decisions from that.&lt;/p&gt;

&lt;p&gt;And if you do need metrics, test, but don't grade based on the results of those tests. Try to avoid letting your measuring instrument influence the results of what you're trying to measure.&lt;/p&gt;

</description>
      <category>career</category>
      <category>interviewing</category>
      <category>hiring</category>
    </item>
    <item>
      <title>React and Redux</title>
      <dc:creator>Kel</dc:creator>
      <pubDate>Mon, 18 Jun 2018 22:07:23 +0000</pubDate>
      <link>https://forem.com/gettingappsdone/react-and-redux-4h7j</link>
      <guid>https://forem.com/gettingappsdone/react-and-redux-4h7j</guid>
      <description>&lt;p&gt;For the longest time after React was released I had difficulty really understanding how it was supposed to be used. Coming from years of MVC/MVVM experience in Java, C#/WPF, and Angular, React seemed strange. The basic tutorials and examples showed 'how' you do something, but never why, and there was pretty much no separation between view and controller logic.&lt;/p&gt;

&lt;p&gt;Eventually I sat down and wrote something using React and Redux, following the 'best practices', so I could understand the decisions that went into the frameworks and how they could be used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;So what did I learn?&lt;/p&gt;

&lt;p&gt;First, React is a different way of thinking of applications, but also, it's almost entirely concerned with view and view state. MVC generally separates the view state from the view and keeps it in the controller along with other application state information and in MVVM, the entire purpose of the 'VM' ViewModel is to keep track of view state. But in React, these two are combined into one abstraction called a "Component".&lt;/p&gt;

&lt;p&gt;Components are relatively simple. They contain the logic for rendering your view to the page given a view state, and optional methods for changing that state.&lt;/p&gt;

&lt;p&gt;A simple 'stateless' component is just the render logic. These can be represented by just a function that take a "props" object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I'm using JSX in these examples. It's a layer on top of your javascript that lets you write HTML-like code elements that are compiled into regular javascript. I recommend reading &lt;a href="https://reactjs.org/docs/introducing-jsx.html"&gt;the JSX intro&lt;/a&gt; for more information. (It also wreaks havoc on my current code highlighter.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Components can contain other components, creating a component 'tree'. In this way, it's just like HTML, where an HTML element can contain other elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;TimeDisplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;It&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TimeDisplay&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toLocaleTimeString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Stateful components that have states that can change are generally more complicated and derived from a 'Component' base class. State updates are triggered by external events (usually UI) by using the setState() function.&lt;/p&gt;

&lt;p&gt;This example will update on every interval "tick" creating a clock.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This example is pulled almost entirely from the React documentation on &lt;a href="https://reactjs.org/docs/state-and-lifecycle.html#adding-lifecycle-methods-to-a-class"&gt;State and Lifecycle&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/decoyahoy/embed/wXJbzz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates, rendering, and the Virtual Dom
&lt;/h3&gt;

&lt;p&gt;When a component updates its state, it causes a re-render. The current component and its children will update.&lt;/p&gt;

&lt;p&gt;Instead of directly updating the DOM, components update the "Virtual DOM", which is a DOM tree in memory. It's not rendered directly to the browser. This virtual DOM is then compared against the 'real' DOM and the real DOM is updated with just the changes between the two.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Uvth1Tfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/react-redux/virtual_dom_diff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Uvth1Tfg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://kellen.piffner.com/img/react-redux/virtual_dom_diff.png" alt="Virtual DOM Diff" title="Virtual DOM Diff"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;cite&gt;&lt;a href="https://github.com/DonaldWhyte/isomorphic-react-workshop"&gt;Image Source&lt;/a&gt;
&lt;/cite&gt;



&lt;p&gt;Combined with the 'reactive' component updates (the component only updates in reaction to setState()), this makes React quite good at only updating what's necessary and minimizing the visible page updates (generally the most computationally expensive part of a change.)&lt;/p&gt;

&lt;p&gt;The trade-off for this performance is higher memory use: The application's component tree is in memory twice. Because this is all abstracted away from the application developer, though, it allows the framework to optimize performance and is generally not something you need to think about.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the rest of the app?
&lt;/h2&gt;

&lt;p&gt;React's simple pattern is quite flexible, allowing for state, view, and events, but it's also quite limiting. The component tree pattern requires your dependencies to be passed through the entire tree to get to child components.&lt;/p&gt;

&lt;p&gt;This can get especially awkward if you introduce a new UI component that needs to reference a piece of application state logic that's not used in that area of the UI. You have to either add it to the all the parent components or alternatively use some kind of js 'global'. Neither is a good solution. Your &lt;em&gt;application&lt;/em&gt; state rarely mirrors the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redux for application state
&lt;/h3&gt;

&lt;p&gt;The solution to this problem is to move the application state into a separate store. The most popular is &lt;a href="https://redux.js.org/"&gt;Redux&lt;/a&gt;, though there are plenty of other options.&lt;/p&gt;

&lt;p&gt;Redux provides three main things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An application level state store.&lt;/li&gt;
&lt;li&gt;A way of updating that store from anywhere in the UI.&lt;/li&gt;
&lt;li&gt;A way of updating the view state of components when the store is updated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Redux is unidirectional, meaning events always go through it in one way.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;React component (events) =&amp;gt; Dispatch (actions) =&amp;gt; Store update (reducer) =&amp;gt; Component update (connect)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's go through this flow in order.&lt;/p&gt;

&lt;p&gt;An event can be generated from anywhere, but is generally a UI event like a mouse click.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Handling events in React has a bunch of caveats. As always, checkout the &lt;a href="https://reactjs.org/docs/handling-events.html"&gt;docs for more information&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SpaceShip&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;moreSpeedClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zoom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;lessSpeedClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mooz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentSpeed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moreSpeedClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;More&lt;/span&gt; &lt;span class="nx"&gt;Speed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lessSpeedClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Less&lt;/span&gt; &lt;span class="nx"&gt;Speed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This event creates a Redux Action. Actions are simple objects that describe what update needs to happen in the store.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// make it go faster by an increment of 1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;faster&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Redux recommends creating "Action Creators", which are just functions that create these objects. Right now our actions are very simple, but in a larger app they might have lots of properties or even logic, so a function helps keep things clean.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;faster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;slower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slower&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;decrement&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;These actions are 'dispatched' through the dispatcher. The dispatcher is passed to the component in its properties and passes action objects to redux.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SpaceShip&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;moreSpeedClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;lessSpeedClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentSpeed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moreSpeedClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;More&lt;/span&gt; &lt;span class="nx"&gt;Speed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lessSpeedClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Less&lt;/span&gt; &lt;span class="nx"&gt;Speed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;The 'store' itself is a plain javascript object. Unlike Angular, the store object isn't directly manipulated or observed by Redux and can be arranged in anyway that makes sense to the application.&lt;/p&gt;

&lt;p&gt;When an action is dispatched to the store, they're passed through functions called 'reducers' which take the previous state and an action, and then returns an updated state object. The common pattern is to use a switch statement on the 'type' of the action objects. Because this is just a function and plain javascript objects, however, you can do whatever you want.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;spaceshipReducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FASTER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SLOWER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;initState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spaceshipReducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;One of the requirements of Redux applications is that your store be "immutable". This means that instead of updating existing objects, you entirely replace them. This allows you to do simple reference comparisons that can greatly impact the performance of larger applications. The downside is it can make your reducers considerably more difficult to read.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this does the same thing as the 'faster' case above&lt;/span&gt;
&lt;span class="c1"&gt;// You would use this pattern for more complex state trees&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Read more in about immutable changes in the &lt;a href="https://redux.js.org/basics/reducers#handling-actions"&gt;redux basics tutorials&lt;/a&gt;. If using newer javascript features, there are a few other options as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After any action is received by the store, it fires an update event. React components are wrapped in a container component that triggers updates when the store updates. A component is wrapped using the redux 'connect' function that maps the application store to the component properties. If you use best practices (immutable), this map is bright enough to tell when that section of the state is different or not. Other than that, the wrapper component doesn't do much magic. It simply subscribes to the store 'update' event and uses setState() when something changes to trigger the normal react update.&lt;/p&gt;

&lt;p&gt;It's also common to map the dispatch actions to properties rather than passing the entire dispatch function in.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;currentSpeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="na"&gt;slower&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SpaceShipContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;
&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;SpaceShip&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;And here's all of it together.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/decoyahoy/embed/xzpEqe?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You'll see a "Provider" component in the full example. The Provider simply makes the redux store available to any connected "container" component without the developer having to do anything. It does this by utilizing some low-level React features that you generally don't need to worry about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Redux Middleware and async actions
&lt;/h3&gt;

&lt;p&gt;This covers the basic cases of reacting to UI events, but doesn't help with working with web services and AJAX callbacks. In the Angular world, these functions are usually placed into services that are injected into your controllers. In general, Redux doesn't provide a solution for this, but what it does provide is a centralized way of passing messages around.&lt;/p&gt;

&lt;p&gt;With Redux, the only things that are injected to a component is the state and dispatcher. The state is just a plain object, but the Redux provides a way of extending the capabilities of the dispatcher through the use of "Middleware".&lt;/p&gt;

&lt;p&gt;Middleware is a function that is called before the action is passed on to the reducer. One of the simplest and most commonly used middlewares is &lt;a href="https://github.com/reduxjs/redux-thunk"&gt;redux-thunk&lt;/a&gt;, which allows you to dispatch async actions. Instead of passing an action object, you pass in a function to the dispatcher. Redux-thunk sees the function and calls it, passing in the dispatcher and state.&lt;/p&gt;

&lt;p&gt;When I say simple, I mean it. Here's the important part of redux-thunk:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;extraArgument&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;If the action is a function, it calls it, passing in the dispatcher, getState accessor, and an optional argument. If the action is not a function, it's just passed on to the default behavior.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; getState() returns the current state at the time of calling. This has two purposes: You can get the state before and after 'dispatch' has been called (letting you perform complex logic in your action creators), and you can get the state after an async action completes (important since the state could have changed since the action began.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an example of what a 'thunk' looks like. Compare this action creator to the 'faster' and 'slower' examples above.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;warpSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// we're using setTimeout for our async action&lt;/span&gt;
    &lt;span class="c1"&gt;// but this could be an http call, or whatever&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// dispatch the state update action&lt;/span&gt;
      &lt;span class="c1"&gt;// this could also be another thunk!&lt;/span&gt;
      &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// warpSpeed returns a function that is called by the middleware,&lt;/span&gt;
&lt;span class="c1"&gt;// but the function signature is the same as before.&lt;/span&gt;
&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warpSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;This simple pattern acts a lot like dependency injection at the function level, or a command/mediator pattern. If you need additional 'services' or configuration you can inject them through the "extra Parameter" option.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;warpSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;extraArgument&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;faster&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;warp&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;extraArgument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warmupTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;I have somewhat mixed feelings on this pattern since it's mixing your store updates and mediated command messages, but passing everything through the dispatcher does keep things simple, so I don't consider it a big deal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other thoughts
&lt;/h2&gt;

&lt;p&gt;Redux is worthy of an entire article. It’s both opinionated, but flexible. I recommend reading through their &lt;a href="https://redux.js.org/introduction"&gt;entire documentation&lt;/a&gt; to really get a handle on how it can be used. Also, by learning Redux you'll have a lot of the basic React concepts reinforced.&lt;/p&gt;

&lt;p&gt;There are also plenty of alternatives. Checkout &lt;a href="https://mobx.js.org/"&gt;MobX&lt;/a&gt; for something more similar to Angular (more magic), or even roll your own (no magic)!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since I wrote this article, I created my own alternative to redux called &lt;a href="https://github.com/honkjs/honk"&gt;Honk&lt;/a&gt;.  It was created for simple projects with typescript in mind.  Check it out!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It should also be mentioned that &lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt; and &lt;a href="https://vuejs.org/"&gt;Vue&lt;/a&gt; are both component heavy now, having taken a lot of cues from React. Learning one will likely help you with the others.&lt;/p&gt;

&lt;p&gt;Finally, I want to mention that react + redux using best practices is &lt;em&gt;verbose&lt;/em&gt;. There's very little 'magic' that hides code from the developer, and combined with redux's "best practices" you end up with lots of extra infrastructure code. The up sides are better understandability - you'll often hear people say react and redux is easier to 'reason' about - and better code separation, especially for larger projects and teams.&lt;/p&gt;

&lt;p&gt;Good luck, and happy coding!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
  </channel>
</rss>
