🔥 (#25) Reduce, reuse, recursion?

Hey there,

Today we're talking reduce, dependency injection, React (don't worry, this is still a Vue newsletter), code comments, and conferences.

But you don't have to take my word for it.

And if you know someone else who would enjoy these tips, forward this email to them or send them here so they can sign themselves up!

— Michael

🔥 Simpler testing with dependency injection

Jest makes it easy to mock or stub out functions, but you can also use dependency injection to make things easy to stub:

export default {
props: {
fetchData: {
type: Function,
required: true,
},
},
methods: {
setText() {
this.text = this.fetchData();
},
},
};
it('should work', () => {
const { getByText } = render(MyComponent, {
props: {
async fetchData() {
return 'Test text';
},
},
});
getByText(/Test text/);
});

(Example is simplified to illustrate the concept)

This is great for mocking API calls, or anything else that's tricky when testing.

If it's coming from outside of the component, it's pretty straightforward to stub it out or mock it however you need, in order to get the test to do what you want.

You can do this in a variety of ways, depending on your use case:

  • props
  • provide/inject
  • Vuex
  • custom plugin

(There are probably many more)

🔥 Reducing Objects

The reduce function is really great for converting arrays into objects, but it can be intimidating.

If we have a bunch of items that all have an id:

{
id,
//...
}

We can reorganize the array into an object, where the key for each item is the item's id:

const obj = arr.reduce((prev, next) => {
// Grab the id from the item
const { id } = next;
// Add the item to our object
prev[id] = next;
// Return the object so we can add more items
return prev;
}, {});

You get an object that looks like this:

{
'id1': { id: 'id1', ... },
'id2': { id: 'id2', ... },
'id3': { id: 'id3', ... },
}

If you want to group all objects in an array by a specific property, you can do something very similar:

const obj = arr.reduce((prev, next) => {
// Grab the property from the item that we want to group by
const { prop } = next;
// Add a new array to the object if this is the first one
// with this value
if (prev[prop] === undefined) {
prev[prop] = [];
}
// Add our item to this array
prev[prop].push(next);
// Return the object so we can add more items
return prev;
}, {});

Our final object looks like this:

{
'prop1': [
{ prop: 'prop1', ... },
{ prop: 'prop1', ... },
{ prop: 'prop1', ... },
],
'prop2': [
{ prop: 'prop2', ... },
{ prop: 'prop2', ... },
{ prop: 'prop2', ... },
],
}

It seems that every week there's a new JS framework, or a new and better way to write CSS (which is just the old way again).

Just as you get comfortable writing unit tests you learn that integration tests are actually the way to go. Oh, and the way you've been writing your tests is completely wrong.

Ugh 🤦‍♂️

It would be so much simpler if we could ignore everything, but hidden among all these new tools are amazing gems that can transform the way we work.

But keeping up with all of them is impossible.

That's why my long time friend, Anthony Gore (who also created Vue.js Developers), created DevTrends.io

He does all of the research on new tech and tools for you, and then teaches you the most important details in short, informative videos.

Click here to check out some recent videos

📜 Vuex — but for React

This is an interesting short read on writing a Vuex clone, but in React.

I've taken lots of ideas from React and used them in Vue over the years, but haven't seen many people take ideas from the Vue ecosystem yet.

What patterns or ideas can you borrow from other frameworks or languages you've used in the past?

Read it here: I wrote Vuex — but for React!

đź—ž News: It's conference season!

Yes, I'm just copying and pasting this section each week.

But you know what? I don't want you to forget about a great conference — like Nuxt Nation, which is happening next week.

We have four incredible conferences coming up in the next 2 months, all accessible online and two offering (limited) in-person experiences:

đź’¬ Comments

"Good code is its own best documentation. As you're about to add a comment, ask yourself, 'How can I improve the code so that this comment isn't needed?'" — Steve McConnell

🧠 Spaced-repetition: Define multiple components in a single file

The best way to commit something to long-term memory is to periodically review it, gradually increasing the time between reviews 👨‍🔬

Actually remembering these tips is much more useful than just a quick distraction, so here's a tip from a couple weeks ago to jog your memory.

Every now and then you just need a small component, one that's not worth an entirely new file:

// A small, secondary component
const SmallComponent = {
// Create a component like you normally would
data() {
//...
},
computedProps: {
//...
},
// Use the template property instead of a template block
template: `
<div>Hello!</div>
`
};
// Your main component
export default {
components: { SmallComponent },
// ...
};

This is perfect for reusing code within a component, where a v-for doesn't work.

However, if the code is more complex or is likely to be used by other components, making a proper reusable component is the best way to go.

Note: You can get proper syntax highlighting of the HTML string using this VSCode extension.



p.s. I also have two courses: Reusable Components and Clean Components