0

I am totally new to React and ES6, and not able to understand how to apply the concept of closure here to update my state. I am working on a react app which uses Draftjs. I need to create a new map of (depth:[...text]) and store it in the component state to refer it later.

Following is my function to do that:

 saveDepthMap(){
    let blockMap = this.state.editorState.getCurrentContent().getBlockMap();
    var depthMap = new Map();

    blockMap.forEach(k => {
        let depth = k.getDepth();
        let text = k.getText();
        if(text.replace(/^\s+|\s+$/g, '') !== undefined){
            console.log(depth, text);
            if(!depthMap.has(depth)) depthMap.set(depth, [text]);
            else depthMap.set(depth, depthMap.get(depth).concat([text]));
        }
    });

    this.setState({
        depthMap
    }, () => {
        console.log(this.state.depthMap, this.state.editorState.getCurrentContent().getBlockMap());
    });
}

First I am saving the current editorstate's blockMap(it is a draftjs map for getting block-level info in the editor). I am successful till this point.

Then i declare a new map and try to store k,v from the blockMap into depthMap using a .forEach() function.

Unfortunately, neither the state is getting updated, nor the depthMap is storing any data after running a forEach() over it.

I think I am going wrong here with the concept of closure or maybe something else.

Omkar
  • 2,274
  • 6
  • 21
  • 34
  • DId u checked `blockMap` by logging it.Use debugger to check it nicely – RIYAJ KHAN Feb 20 '18 at 05:37
  • @RIYAJKHAN I do have the blockMap loaded correctly. The problem is with the closures here i suppose.. – Omkar Feb 20 '18 at 05:39
  • @Herohtar isnt it an ES6 syntax ? You dont need to use `:` if you have the same variable names? – Omkar Feb 20 '18 at 05:40
  • @Omkar `depthMap` declared at functional scope.So,dont think issue will arise to access it – RIYAJ KHAN Feb 20 '18 at 05:40
  • this.setState() is asynchronous, so it is firing before your forEach function – Chris Feb 20 '18 at 05:41
  • @RIYAJKHAN thats why i put a console.log() to check the k,v of the blockMap.. it looks good. – Omkar Feb 20 '18 at 05:43
  • @Chris that might be the case... but not sure how to really work here with it then... any idea for my case? – Omkar Feb 20 '18 at 05:46
  • 1
    @Chris No, asynchronous code doesn't magically run out of order. The `forEach` will execute synchronously before execution reaches the `setState` call. – Herohtar Feb 20 '18 at 05:47
  • @Omkar You're right, I wasn't aware of that. – Herohtar Feb 20 '18 at 05:51
  • I created a basic test in my React app using the same `forEach` structure followed by `setState` with a callback and the state is updated correctly. It looks like it would have to be a problem with your block map somehow, though you say the log statement in the forEach is printing correctly, so I don't know... – Herohtar Feb 20 '18 at 06:07
  • @herohtar not sure what’s the issue, but will replicate it tomorrow morning yo check.. – Omkar Feb 20 '18 at 06:12

1 Answers1

-2

React setState() method takes a javascript object. You should use it like this

this.setState({ depthMap: newDepthMap }) //considering the newly created is newDepthMap  
izengod
  • 1,116
  • 5
  • 17
  • 41
  • setState is used correctly, it takes a callback, check this https://stackoverflow.com/questions/42038590/when-to-use-react-setstate-callback/42038724#42038724 – Shubham Khatri Feb 20 '18 at 05:43
  • 2
    @izengod it doesnt matter if you use a newDepthmap or just depthMap, its an ES6 syntactic sugar of simply using the name if it matches the variable in your state. – Omkar Feb 20 '18 at 05:44