Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Remon Fawzi
Remon Fawzi

Posted on

     

Write better JavaScript and ReactJs code with Immerjs

What is an immutable state?

It's a state that doesn't change over time.

So when we create an immutable object we don't change it's properties, If we need to change it's properties, we create a new copy of it and modify the properties as we want.

In JavaScript we can use both mutable and immutable states, We decide which is better for us, We can useObject.freeze() for example to make our object immutable.

Let's have an example, We've an object called state ...

conststate={id:1,name:'John',accounts:{facebook:{id:'facebook',url:'/'},twitter:{id:'twitter',url:'/'}}};
Enter fullscreen modeExit fullscreen mode

We need to modify it's twitter account url and assign it to a new state without affecting the current state, So we would do something like this

constnewState={...state,accounts:{...state.accounts,twitter:{...state.accounts.twitter,url:'/newUrl'}}};
Enter fullscreen modeExit fullscreen mode

This code has two main issues

  1. It's so long in comparison to its purpose, I just want to update one property.
  2. Readability is not so good, Why I'm seeing many properties and nested levels while I'm only updating one property?!

If we use ImmerJs, It'll be like this

constnewState=produce(state,(draftState)=>{draftState.accounts.twitter.url='/newUrl';});
Enter fullscreen modeExit fullscreen mode

Here, we can see

  1. Shorter code
  2. More readable, I'm only seeing the property I'm changing!

So, Immerjs produce function creates a new draft copy of your object or array, And let you modify it as you want, Then returns you a new state with the changes you applied.

In React

All states are immutable, When we set a state we create a new variable and assign it to the state, We don't change the current one

Let's have an example

const[quiz,setQuiz]=useState({title:"Quiz 1",questions:[{id:"1",type:"mcq",title:"Question 1?",answers:[{id:"a_1",text:"Answer 1",isTrue:true},{id:"a_2",text:"Answer 2",isTrue:false}]}]});
Enter fullscreen modeExit fullscreen mode

We've a state holds an object, What if we want to push a new answer to the quiz? We would do something like this

constaddAnswer=(questionId,newAnswer)=>{setQuiz({...quiz,questions:quiz.questions.map((question)=>question.id===questionId?{...question,answers:[...question.answers,newAnswer]}:question)});};
Enter fullscreen modeExit fullscreen mode

Complex, right? Here's how it's done using Immerjs

constaddAnswer=(questionId,newAnswer)=>{setQuiz(produce(prev,(draft)=>{constquestion=draft.questions.find((el)=>el.id===questionId);question.answers.push(newAnswer);});};
Enter fullscreen modeExit fullscreen mode

So it's not just about reducing amount of code, But we only focus on what we need to change "The answer", without caring about the other quiz properties.

There's also a light packageuse-immer contains a custom hook useImmer, It's used instead of useState to call the produce function automatically when setting a state

const[quiz,setQuiz]=useImmer({.....});
Enter fullscreen modeExit fullscreen mode

It'll make our code more simpler

constaddAnswer=(questionId,newAnswer)=>{setQuiz((draft)=>{constquestion=draft.questions.find((el)=>el.id===questionId);question.answers.push(newAnswer);});};
Enter fullscreen modeExit fullscreen mode

This awesome packageimmerjs makes Redux toolkit too much simpler than old redux pattern, It's automatically implemented there, So you don't need to use the many spread operators just to change one value in your reducers.

Thank you so much!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Front-End Engineer
  • Location
    Cairo
  • Work
    Front-End Engineer at Q84Sale
  • Joined

More fromRemon Fawzi

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp