When working with JavaScript, React, Redux, and functional programming, you’ll often come across terms like:
Let’s break down what these terms mean, how they’re used in JavaScript, and clear up any confusion surrounding them.
Mutations

In programming, mutation means changing the state of an object, variable, or data structure after it’s been created. And no, sadly, it has nothing to do with Ninja Turtles or X-men.
In JavaScript, primitive values (all data types except objects) are immutable, meaning they cannot be changed, but can be reassigned.
You might have heard that let is mutable, while const is not — but that’s not quite true.
The difference between let
and const
lies in the fact that const
cannot be reassigned. However both let
and const
containing the objects or arrays are not immutable.
Example
const person = {name: 'Cassius Marcellus Clay'};
person.name = 'Muhammad Ali';
In this example, the name
property of the person
object is changed. This is a mutation.
Why is it considered bad?
Mutations aren’t inherently harmful, but they can lead to errors and make code harder to understand.
A short example:
const a = [1, 2, 3];
const b = a;
b.push(4);
console.log(a); // [1, 2, 3, 4]
In this example, we mutate the array b
, but it points to the same object as a
. This can lead to unpredictable behavior.
To avoid this, as a simpliest option you can use methods that return a new object instead of mutating the old one:
const a = [1, 2, 3];
const b = {...a, 4};
console.log(a); // [1, 2, 3]
Immutability in React/Redux
React
One of the key rules of React is that props and state should be immutable.
Redux
Similarly in Redux, the first rule in the Redux Style Guide is to avoid mutating state.
Libraries for working with immutability
To avoid mutations, you can use the built-in JavaScript method Object.freeze
or libraries that help with immutability, such as:
Side Effects

A side effect is any change in the system that affects the outside world.
This might sound a bit abstract right now.
For example, when you call a function, your computer works harder, generating heat. This heat might gradually increase the room temperature. Can we consider this a side effect of the function?
Well, it depends on the context:
In the context of physics — yes. But in the context of the software we’re developing — no. In programming, side effects usually refer to what happens within the program, such as:
- Modifying a global variable.
let counter = 0;
function increment() {
counter++; // Side effect: changes external state
}
increment();
console.log(counter); // 1
- Logging to the console.
function logMessage(message) {
console.log(message); // Side effect: output to the console
}
logMessage('Hello, world!');
Logging doesn’t change the program state, but it affects the runtime environment by leaving a trace in the console.
- Modifying the DOM.
function updateTitle(newTitle) {
document.title = newTitle; // Side effect: changes the page title
}
updateTitle('New Title');
console.log(document.title); // "New Title"
Side Effects in React/Redux
React
In functional components, side effects are managed with the useEffect
hook. You can use it for tasks like:
- Making API calls
useEffect(() => {
fetch('https://api.example.com/data')
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then((data) => setData(data))
.catch((error) => console.error('Fetch error:', error));
}, []);
It’s worth mentioning that for API calls, it’s often better to use libraries like React Query or SWR, which make your code easier to manage.
- Event subscriptions
useEffect(() => {
const handleOffline = () => setIsOffline(true);
const handleOnline = () => setIsOffline(false);
window.addEventListener('offline', handleOffline);
window.addEventListener('online', handleOnline);
return () => {
window.removeEventListener('offline', handleOffline);
window.removeEventListener('online', handleOnline);
};
}, []);
- Working with local storage
useEffect(() => {
const data = JSON.parse(localStorage.getItem('data'));
setData(data);
}, []);
- Manipulating the DOM
useEffect(() => {
document.title = 'New Title';
}, []);
Redux
In Redux, handling side effects is achieved through middleware.
The most popular middleware for this is Redux Thunk.
const fetchUserById = createAsyncThunk('users/fetchByIdStatus', async (userId: number, thunkAPI) => {
const response = await userAPI.fetchById(userId);
return response.data;
});
Pure Functions
Pure functions are functions that have two properties:
- They have no side effects.
- They are deterministic, meaning that given the same input, they always produce the same output.
Let’s look at a couple of examples:
Examples
Is this function pure?
function addRandom(a) {
return a + Math.random();
}
To figure this out, we need to answer two questions:
- Does this function have side effects?
No, there are no side effects here.
- Is this function deterministic? In other words, does it always return the same result for the same input?
No, this function is not deterministic because Math.random()
returns a random number. So, the first call to addRandom(2)
might return 2.123
, while the second call could return 2.456
.
Therefore, this function is not pure.
What about this one?
function add(a, b) {
return a + b;
}
This function meets both requirements for a pure function: it has no side effects and is deterministic.
Pure Functions in Redux
One of the three core principles of Redux is using pure functions.
Idempotent Functions


The term “idempotence” means that doing the same operation over and over again doesn’t change anything after the first time.
A function is idempotent if calling it multiple times with the same input gives the same result as calling it once.
In other words, calling the function f(x)
multiple times, like f(x); f(x); f(x);
, gives the same result as calling it once: f(x);
.
(Note that in mathematics, idempotence means f(f(x)) = f(x)
, but that’s a slightly different story. If you’re interested, you can read more about it in Kyle Simpson’s excellent book Functional-Light JavaScript).
Examples
function convertToUpper(str) {
return str.toUpperCase();
}
This function is idempotent because calling it 10 times has the same effect as calling it once.
This function is also pure. While pure functions are always idempotent, not all idempotent functions are pure.
function setUserActive(user) {
user.status = 'active';
}
This function is idempotent because each call with the same user
object will set the status to active
.
However, it is not a pure function because it mutates the user
object.
function addHiddenClass(element) {
element.classList.add('hidden');
}
Similarly, the addHiddenClass
function is idempotent: after the first call, the hidden
class is added to the element, and subsequent calls do not change the state.
However, since it mutates the DOM, it is not a pure function.
We won’t provide specific examples in React/Redux because the term idempotence is more commonly used in the context of APIs or HTTP methods.
Conclusion
That’s all for now! I hope this article helped clarify these terms. If you have any questions or notice an error, feel free to drop a comment or reach out using the contact info in the footer.