Showing posts with label Frameworks. Show all posts
Showing posts with label Frameworks. Show all posts

Friday, December 27, 2019

Immutable Update Patterns

Updating Nested Objects

The key to updating nested data is that every level of nesting must be copied and updated appropriately. This is often a difficult concept for those learning Redux, and there are some specific problems that frequently occur when trying to update nested objects. These lead to accidental direct mutation, and should be avoided.
Common Mistake #1: New variables that point to the same objects
Defining a new variable does not create a new actual object - it only creates another reference to the same object. An example of this error would be:
This function does correctly return a shallow copy of the top-level state object, but because the nestedState variable was still pointing at the existing object, the state was directly mutated.
Common Mistake #2: Only making a shallow copy of one level
Another common version of this error looks like this:
Doing a shallow copy of the top level is not sufficient - the nestedState object should be copied as well.
Correct Approach: Copying All Levels of Nested Data
Unfortunately, the process of correctly applying immutable updates to deeply nested state can easily become verbose and hard to read. Here's what an example of updating state.first.second[someId].fourth might look like:
Obviously, each layer of nesting makes this harder to read, and gives more chances to make mistakes. This is one of several reasons why you are encouraged to keep your state flattened, and compose reducers as much as possible.

Inserting and Removing Items in Arrays

Normally, a Javascript array's contents are modified using mutative functions like push, unshift, and splice. Since we don't want to mutate state directly in reducers, those should normally be avoided. Because of that, you might see "insert" or "remove" behavior written like this:
However, remember that the key is that the original in-memory reference is not modified. As long as we make a copy first, we can safely mutate the copy. Note that this is true for both arrays and objects, but nested values still must be updated using the same rules.
This means that we could also write the insert and remove functions like this:
The remove function could also be implemented as:

Updating an Item in an Array

Updating one item in an array can be accomplished by using Array.map, returning a new value for the item we want to update, and returning the existing values for all other items:

Immutable Update Utility Libraries

Because writing immutable update code can become tedious, there are a number of utility libraries that try to abstract out the process. These libraries vary in APIs and usage, but all try to provide a shorter and more succinct way of writing these updates. Some, like dot-prop-immutable, take string paths for commands:
Others, like immutability-helper (a fork of the now-deprecated React Immutability Helpers addon), use nested values and helper functions:
They can provide a useful alternative to writing manual immutable update logic.

Sunday, September 15, 2019

How to obfuscate or minify react javascript source code?


First of all, what is obfuscation of javascript code?

Obfuscation is the deliberate act of creating obfuscated code, i.e. source or machine code that is difficult for humans to understand. It is something similar to encryption however machine can understand the code and able to execute the code.

For example -- Original code:

function hello(name) {
console.log('Hello, ' + name);
}
hello('New user');
After Obfuscation:
eval(function(p,a,c,k,e,d{e=function(c{returnc};if(!''.replace(/^/,String)){while(c--){d=k||c}k=[function(e){return d[e]}];e=function({return'\\w+'};c=1};while(c--){if(k{p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k)}}return p}('3 0(1{2.4(\'5,\'+1)}0(\'76\');',8,8,'hello|name|console|function|log|Hello|user|New'.split('|'),0,{}))
What is minifies source code?
Minification is performed after the code for a web application is written, but before the application is deployed. When a user requests a webpage, the minified version is sent instead of the full version, resulting in faster response times and lower bandwidth costs. Minification is used in websites ranging from small personal blogs to multi-million user services.

Minification also a type of obfuscation here empty spaces will be removed and variables will be renamed.
React minifies the code during the build and generates source maps. JS ends up being sort of obfuscated as a byproduct of minification, not because of secrecy (well, that too, to some extend). That way, the end users are able to load scripts faster than if they were not minified, and you (and everybody else) get to navigate around original code when you (or they) open Developer Tools.

If you take a look in build/static/js directory after the build, there are pairs of .js and .mapfiles. JS files are loaded with your website, and .map files are loaded on demand, when Developer Tools are opened.
To disable sourcemap generation, run your build with GENERATE_SOURCEMAP environment variable set to false.
GENERATE_SOURCEMAP=false npm run build
or
GENERATE_SOURCEMAP=false yarn build
or make it part of build script in package.json
  {
    …
    "scripts": {
      …
-     "build": "react-scripts build"
+     "build": "GENERATE_SOURCEMAP=false react-scripts build"
    }
  }
If you omit the SOURCEMAP generation, .map files will not end up in production, and your original source code will not be available for anyone (including you).

Monday, September 2, 2019

How to wait for a few seconds then redirect to another page in React


It took me a bit of thinking to make the redirect work smoothly. This is the use case in my react app, users can look at the course details info, and attempt to register a course, if user doesn't log in yet, the registration page should redirect user to a login page, after display a message that user needs to login to register for 5 seconds. Here is what we need to do:

state = {
    redirect: false // add a redirect flag
};

componentDidMount() {
    // only change the redirect flag after 5 seconds if user is not logged in
    if (!auth) {
        this.timeout = setTimeout(() => this.setState({ redirect: true }), 5000);
    }
}

componentWillUnmount() {
    // clear the timeer just in case
    clearTimeout(this.timeout);
}

render() {
    // this is the key:
    // 1. when this is first invoked, redirect flag isn't set to true until 5 seconds later
    // 2. so it will step into the first else block
    // 3. display content based on auth status, NOT based on redirect flag
    // 4. 5 seconds later, redirect flag is set to true, this is invoked again
    // 5. this time, it will get into the redirect block to go to the sign in page
    if (this.state.redirect) {
        return <Redirect to="/signin" />;
    } else {
        if (!auth) {
            return (
                <div className="center">
                    <h5>You need to login first to register a course</h5>
                </div>
            );
        } else {
            return <div>Registration Page</div>;
        }
    }
}