# 4 JavaScript Concepts You Need To Know Before You Can Master React

If you’re new to React, you’ve probably heard people tell you that you should learn JavaScript first.

While that’s good advice, it can be overwhelming.

JavaScript isn’t something you’ll be able to master in a few hours. Trying to learn everything about JavaScript before you move to React isn’t worth the time. Instead, focusing on important JavaScript concepts that are often *used* in React will get you much further.

You’ll waste less time with Learner's Fatigue and start building applications faster.

In this post, we’ll take a look at 4 JavaScript concepts that you’ll see in most — if not all — React code.

## 1. Closures

> A **closure** is the combination of a function bundled together (enclosed) with references to its surrounding state (the **lexical environment**).

The quote above is from MDN. If you want an in-depth explanation of what a closure is and how it works, take a look at [MDN’s page on closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures).

Instead of re-hashing the MDN page, I’m going to show you what a closure is through code:

```js
function createACounterClosure() {
	let count = 0;

	function increaseCount() {
		count = count + 1;
	}
	
	function getCount() {
		return count;
	}
	
	return { increaseCount, getCount };
}

const counter = createACounterClosure();

counter.getCount(); // 1
counter.increaseCount();
counter.getCount(); // 2
counter.count; // undefined
```

The combination of the `increaseCount` function and the `count` variable is a **closure**.

There's no way to access `count` directly. However, you can use either function that *closes* over the `count` variable to interact with it. Even though `createACountClosure` has finished running, the `count` variable is still accessible.

Here’s an example of how React uses closures:

```jsx
function MyComponent() {
	const [count, setCount] = React.useState(0);
	React.useEffect(function effectClosure() {
		console.log(count);
		return function cleanupClosure() {
			console.log(count);
		}
	}, [count]);
}
```

Effects are used all the time in React.

The function you pass to and return from `useEffect` both close over the `count` variable. React calls the `cleanupClosure` function sometime in the future when `count` changes.

The key is that the function still has access to the `count` variable even after `effectClosure` returns.

## 2. Array Functions

Almost all React applications use arrays to render lists of components.

Learning basic array functions will help you write better React code. It lets you build components in a declarative style which is easier to maintain and understand.

The most common array functions I see in React code are the following:

- map
- filter
- includes
- find

### map

The `map` function lets you execute a function for each item in an array. A new array is returned where each value is the result of executing the mapper on the original item.

```jsx
const array = [1, 2, 3];
const mappedArray = array.map(function double(item) {
	return item * 2;
});
mappedArray; // [2, 4, 6]
```

### filter

The `filter` function also lets you execute a function for each item in an array. A new array is returned where an item is excluded if the function returns `false`.

```jsx
const array = [1, '2', 3];
const filteredArray = array.filter(function isNumber(item) {
	return typeof item === 'number';
});
filteredArray; // [1, 3];
```

### includes

The `includes` function lets you check if an item is in an array.

```jsx
const array = [1, 2, 3];
array.includes(2); // true
array.includes(4); // false
```

### find

The `find` function executes a function for each item in an array and returns the first element where the function evaluates to true.

```jsx
const array = [1, 2, 3, 4];
const num = array.find(function biggerThan2(item) {
	return item > 2;
});
num; // 3
```

Here’s an example that uses the `filter` and `map` functions in React:

```jsx
const names = ['Jack', 'Jill', 'James', 'Bill'];
function MyComponent() {
	const jNames = names.filter(function isJName(name) {
		return name.startsWith('J');
	});

    const nameItems = jNames.map(function buildNameItem(name) {
        return <span key={name}>Name: {name}</span>;
    });

    return <div>{nameItems}</div>;
}
```

## 3. Destructuring

Destructuring lets you *unpack* array values or object properties into variables.

```jsx
// Normal:
const array = [1, 2];
const person = { name: 'Jack', age: 100 };
array[0]; // 1
array[1]; // 2
person.name; // 'Jack'
person.age; // 100

// Destructure:
const [a, b] = [1, 2];
const { name, age } = { name: 'Jack', age: 100 };
a; // 1
b; // 2
name; // 'Jack'
age; // 100
```

When you destructure an array, you can name the variables anything you want. However, if you destructure an object then the variable names have to match the property you’re trying to destructure.

This is a common pattern in React.

The `useState` hook is a great example. It returns an array with the state and a function to update the state. It’s common to destructure those properties with descriptive names.

```jsx
function MyComponent() {
	const [count, setCount] = React.useState(0);
	count; // The initial value 0
	setCount; // A function to update the state value
}
```

## 4. Object References

Object references are often misunderstood.

If you’re not careful it can lead to mutation bugs.

Mutation bugs are common when more than one variable references the same object in memory. Changing the object from one variable can lead to unexpected effects for the second variable. While mutation isn’t inherently bad, it can lead to bugs that are hard to solve.

Understanding the basics of mutation will help you write better React code.

In JavaScript, when you assign an object to a variable, it points to the object's *reference* in memory. When you compare two objects, you’re really checking if the variables point to the same place in memory. This is why you see things like the following:

```js
const objOne = {};
const objTwo = {};
const objThree = objOne;

objOne === objTwo; // false (refers to different locations in memory)
objOne === objThree; // true (refers to the same location in memory)
```

### Object mutation is reflected in every variable that references it

```js
const objOne = {};
const objTwo = objOne;

objOne.age = 100;
objTwo.age; // 100
```

Both objects refer to the same location in memory. Updating one variable is reflected in the other variable.

### Arrays and Functions

In JavaScript, everything that isn’t a primitive value is an object.

This means that variables containing arrays and functions also behave the same way.

```js
const fnOne = () => true;
const fnTwo = () => true;
fnOne === fnTwo; // false

const arrOne = [];
const arrTwo = [];
arrOne === arrTwo; // false
```

### Object references in React state

React can bail out of a render caused by a state update if the updated state is the same as the old state.

```jsx
function MyComponent() {
	const [count, setCount] = React.useState(0);

	React.useEffect(() => {
		// 0 === 0
        // React will bail out of the render
		setCount(0);
	}, []);
}
```

React improves performance by skipping updates that would result in the same output.

But what happens when we store an object in state?

```jsx
function MyComponent() {
	const [person, setPerson] = React.useState({ name: 'Sai', age: 100 });

	React.useEffect(() => {
		const newPerson = person;
		newPerson.age = 200;

		// newPerson === person (same reference)
		// React will bail out of the render
		setPerson(newPerson);
	}, []);
}
```

Obviously, this isn’t what we want.

So how do we get around it?

```jsx
function MyComponent() {
	const [person, setPerson] = React.useState({ name: 'Sai', age: 100 });

	React.useEffect(() => {
		// Create a new object
		const newPerson = { name: person.name, age: 200 };

		// newPerson !== person (different reference)
		// React won't bail out of the render
		setPerson(newPerson);
	}, []);
}
```

### Object references in React dependency arrays

Another common source of confusion is React dependency arrays.

React uses dependency arrays for `useEffect`, `useCallback` and `useMemo`. It does a shallow comparison (`===`) between renders to check if it needs to do work. This leads to a similar problem as the `useState` use case.

```jsx
function MyComponent() {
	const doSomething = () => {
		// ...
	};
	
	const value = React.useMemo(() => doSomething(), [doSomething]);
	const callback = React.useCallback(doSomething, [doSomething]);
	React.useEffect(() => {
		doSomething();
	}, [doSomething]);
}
```

The `doSomething` function is used in all of the dependency arrays above.

The problem is that `doSomething` is recreated *every* render cycle, so its reference is different. When React compares `doSomething` between render cycles, each version will point to a different location in memory. This means that each hook will execute *every* time the component renders which is probably not what we want.

Here are a couple of things you can do instead:

```jsx
const doSomethingExternal = () => {};

function MyComponent() {
	const doSomething = React.useCallback(() => {
		// ...
	}, []);
	
	const value = React.useMemo(() => {
		if (/* true */) return doSomething();
		return doSomethingExternal();
	}, [doSomething]);

	React.useEffect(() => {
		doSomething();
		doSomethingExternal();
	}, [doSomething]);
}
```

One solution is to define a function outside of the component. This guarantees that the reference is the same between renders because the function is only defined once. You can also define a function with the `useCallback` hook. This also guarantees referential stability between renders which makes it safe to use in dependency arrays.

## Conclusion

You need to understand the basics of JavaScript before you can use React effectively.

However, there's no need to try to master everything. It's better to focus on the important parts and try to apply what you've learned directly in React. It adds context to how concepts are used in real applications. This leads to a deeper understanding.

In the end, you're probably trying to use JavaScript to write React code.

So do that.
