Categories
Redux

Intro to React State Management with React-Redux

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

To store data in a central place for easy accessibility by components, we have to use some state management solutions. React-Redux is a popular choice.

In this article, we’ll look at how to add it to our React app and simple use cases.

Installation

To install the react-redux package, we have install react-redux and its dependency redux .

We can install both by running:

npm install react-redux redux

with NPM or if we use Yarn:

yarn add react-redux redux

Set Up a Redux Store

After installing both packages, we have to set up our Redux store to hold our data.

To do this we write:

import { createStore } from "redux";

function counterReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

The code above creates a Redux store by creating the counterReducer reducer function.

The reducer specifies how the app’s state changes in response to actions sent to the store.

Our counterReducer only accepts one action, which is 'INCREMENT' . We respond to the action by returning the state and adding 1 to it.

There’s also a default case to just return the state value as is.

Then we create a store by calling Redux’s createStore function and passing in our reducer.

It returns the store , which we can pass into our React app.

Connecting the Store to our React App

This is where we need the functions of React-Redux.

We can connect the store to our app so we can store our app’s state in the store by using React-Redux’s connect function.

connect takes 2 functions, which are mapStateToProps and mapDispatchToProps . They’re the first and second argument respectively.

First, we can put the whole app together by connecting our store with the React app as follows:

import React from "react";
import { Provider, connect } from "react-redux";
import { createStore } from "redux";
import ReactDOM from "react-dom";

function counterReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

class App extends React.Component {
  onClick() {
    this.props.increment();
  }
  render() {
    const { count } = this.props;
    return (
      <>
        <button onClick={this.onClick.bind(this)}>Increment</button>
        <p>{count}</p>
      </>
    );
  }
}

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" })
  };
};
const mapStateToProps = state => ({
  count: state
});

App = connect(
  mapStateToProps,
  mapDispatchToProps
)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);

In the code, we have an app that shows a number going up as we click the Increment button.

The first step to connect the store to our React app is to wrap the Provider component around our whole app.

To do this we, wrote the following:

<Provider store={store}>
  <App />
</Provider>

Then we define the mapStateToProps and mapDispatchToProps functions as follows:

const mapDispatchToProps = dispatch => {
  return {
    increment: () => dispatch({ type: "INCREMENT" })
  };
};
const mapStateToProps = state => ({
  count: state
});

In mapStateToProps we return a object to map the state object to a React component prop name as indicated in the property name. The state is the state stored in the Redux store.

So we mapped state to the prop count .

In mapDispatchToProps , we get the dispatch parameter, which is a function used to dispatch our action to the store, and return an object with the name for the function we can access from the props to call and dispatch the action.

So in mapDispatchToProps , increment is our function name. We can call it by running this.props.increment in our App component.

increment is a function that runs dispatch({ type: “INCREMENT” }) .

Then in our App component, we define the onClick method to call this.props.increment to dispatch the ‘INCREMENT’ action to our counterReducer via our Redux store and increase the state by 1.

Then since we have mapStateToProps , the latest value is being observed by App and the latest value is available via this.state.count as indicated in mapStateToProps .

Then when we click the Increment button, we’ll get the number going up by 1.

This will happen with every click.

Conclusion

We can use Redux in our React app by creating a store.

Next, we use the React-Redux Provider component and wrap it around our App entry-point component. We pass our Redux store to the store prop so that we can map the state and dispatch actions to props.

Then connecting it to our store via React Redux’s connect function. We pass in the mapStateToProps and mapDispatchToProps to map the store’s state to our component’s props and map our dispatch function call to our props respectively.

Categories
JSON

Working with JSON — Schemas and CSRF

JSON stands for JavaScript Object Notation.

It’s a popular data-interchange format that has many uses.

In this article, we’ll take a look at how to use JSON.

JSON Schemas

We can check the value of JSON schemas to check if our data types are correct.

Also, we can check if we have the required data.

And we check if the values are in the format that we require.

For example, if we have:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Person",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "number",
            "description": "Your person's age in years."
        },
        "gender": {
            "type": "string"
        },
        "description": {
            "type": "string"
        }
    },
    "required": [
        "name",
        "age",
        "gender"
    ]
}

then we have a Person schema that has the name with type string .

The age property has type number .

gender is of type string and description is also of type string .

Also, it has the required property that has an array of required properties.

For example, if we have:

{
    "name": "james",
    "age": 2,
    "gender": "male"
}

then it conforms to the schema that we just created above.

We can add more validation to our schema.

We can set the minimum number allowed for age .

For example, we can write:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Person",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "number",
            "description": "Your person's age in years.",
            "minimum": 0
        },
        "gender": {
            "type": "string"
        },
        "description": {
            "type": "string"
        }
    },
    "required": [
        "name",
        "age",
        "gender"
    ]
}

to set the minimum allowed value for age .

Then if we want to validate an object against our schema, we can go to https://www.jsonschemavalidator.net/.

If we have anything that doesn’t conform to the schema we specified, we’ll see the errors.

We put the schema object on the left side and the JSON object we want to check against on the right side.

JSON Security

Since we’re using JSON to communicate between 2 or more parties, we’ll have to look at security.

Anything that communicates over a network will have security risks.

There are various kinds of attacks that we have to concerned about.

Cross-Site Request Forgery (CSRF)

One kind of attack that we have to worry about is the cross-site request forgery.

This where an attack goes to a site that is already authenticated by a legitimate user.

So the attacker can see the sensitive data that is in the site.

Attackers can gain access to sites that require authentication because cookies are included with requests, so they may be able to intercept them and use them to authenticate.

There’s no way to distinguish between legitimate requests and forged requests unless a CSRF token is used to distinguish between them.

Most web frameworks have protection for this attack built in to stop this attack.

Conclusion

We can validate JSON schemas against our JSON objects to validate our objects with it.

Also, we have to be careful about CSRF attacks to stop attackers from accessing sensitive data with forged requests.

Categories
JSON

Working with JSON — Injection Attacks

JSON stands for JavaScript Object Notation.

It’s a popular data-interchange format that has many uses.

In this article, we’ll take a look at how to use JSON.

Injection Attacks

Injection attacks are where attackers run their own malicious code on our websites to do what they want.

They add their own malicious code onto our sites and run them by exploiting the vulnerabilities on our site.

Cross-Site Scripting (XSS)

One kind of injection attack is the cross-site scripting attack.

This is where the attack runs their malicious code on our site by using the vulnerabilities on our site.

JavaScript has the eval function that takes a string and run code form it.

For example, if we have:

const jsonString = '{"animal":"cat"}';
const obj = eval(`(${jsonString})`);
console.log(obj.animal);

Then we put the jsonString in the parentheses and run that with eval .

A JavaScript object will be returned and we assign that to obj .

So when we console log the value of obj.animal , we get 'cat' .

As we can see, this can lead to problems when we have malicious code as the argument of eval .

For example, if we have:

const jsonString =  "alert('bad')";;
const obj = eval(`(${jsonString})`);

Then eval runs the code in jsonString to show an alert box.

That is definitely not good since it’s doing something users don’t expect.

Fortunately, this attack is recognized by developers and the JSON.parse method won’t parse JSON strings with functions in them.

Therefore, we should use JSON.parse instead of eval to parse JSON strings:

const jsonString = '{"animal":"cat"}';
const obj = JSON.parse(jsonString);
console.log(obj.animal)

We parse jsonString with JSON.parse instead and get the same result as the previous example.

This is supported by almost all modern browsers so we can use this to parse JSON strings without thinking.

We should also think about HTML strings that have JavaScript.

For example, we can write:

{
    "message": "<div onmouseover=\"alert('gotcha!')\">hover here.</div>"
}

The string calls alert in the HTML code when we hover over the rendered HTML.

This is something that we have considered when we are parsing HTML strings and rendering them directly in the browser.

It can do a lot more than just showing an alert, and do things like stealing data.

A good way to prevent parsing raw HTML and JavaScipt directly is to escape the HTML characters.

We can convert <div> to &lt;div&gt; so that it won’t be rendered as HTML.

Instead, the code will be displayed as the code.

Modern web frameworks should prevent raw HTML from being rendered directly in the browser unless we explicitly make it do so.

Conclusion

We should watch out for cross-site scripting attacks when we’re writing our sites and web apps.

Modern web frameworks should prevent raw HTML from being rendered directly.

Also, we shouldn’t use eval to run raw JavaScript code.

Categories
JSON

Working with JSON — Syntax Rules and Data Types

JSON stands for JavaScript Object Notation.

It’s a popular data-interchange format that has many uses.

In this article, we’ll take a look at how to use JSON.

Syntax Validation

We can validate the syntax for JSON with many tools.

Many IDEs like WebStorm and text editors like Visual Studio Code have JSON validation capabilities built-in.

There are also many websites that let us validate our JSON code.

They include:

They all provide syntax highlighting and will show errors if there are any errors with the syntax.

JSON as a Document

JSON can be used as documents. We just have to save it with the .json extension to use them.

The JSON MediaType

JSON has its own MIME type, which is application/json .

It’s a standard Internet media type that we can use for communication.

JSON Data Types

JSON lets us add values with a few data types into our object.

They include numbers, characters and strings, and booleans. These are primitive data types, which are the most basic data types.

We can also add the array composite data type, which is something composed of primitive data types.

In JSON, the allowed data types are:

  • Object
  • String
  • Number
  • Boolean
  • Null
  • Array

The JSON object data type is the root data type.

The root of a piece of JSON data is either an object or an array.

For instance, we can write:

{
    "person": {
        "name": "james smith",
        "heightInCm": 180,
        "head": {
            "hair": {
                "color": "brown",
                "length": "short",
                "style": "A-line"
            },
            "eyes": "blue"
        }
    }
}

to add an object with key-value pairs that describe a person.

It has the person key which is set to an object value.

There are also other object values like head and hair .

heightInCm has a number value.

JSON String Data Type

One of the basic JSON data types is a string.

A string has any text data.

A JSON string can be comprised of any Unicode character.

A string must always be enclosed in double-quotes.

For example, we can’t write:

{
    'title': 'title.',
    'body': 'body.'
}

but we can write:

{
    "title": "title.",
    "body": "body."
}

If we want to add double quotes in a string, we can use the backslash to escape them.

For instance, we can write:

{
    "promo": "Say \"cheese!\""
}

to add the double quotes inside the string by adding a backslash before it.

If we want to add a backslash into a string, then we have to add 2 backslashes:

{
    "path": "C:\\Program Files"
}

Other characters that have to escaped include:

  • / (forward slash)
  • b (backspace)
  • f (form feed)
  • t (tab)
  • n (newline)
  • r (carriage return)
  • u followed by hexadecimal characters

For example, we can use them by writing:

{
    "story": "\t Once upon a time, \n there was a prince."
}

We added the tab character with \t and a newline with \n .

Conclusion

We can validate JSON syntax with many tools.

Also, there are a few data types that are supported in JSON.

Special characters also have to be escaped.

Categories
JSON

Working with JSON — Data Types and Schemas

JSON stands for JavaScript Object Notation.

It’s a popular data-interchange format that has many uses.

In this article, we’ll take a look at how to use JSON.

JSON Number Data Type

Numbers are supported with JSON.

We just add them as values.

For example, we can write:

{
    "latitude": 49.606209,
    "longitude": -122.332071
}

to add the numbers as the values.

We have decimal numbers in the JSON. We can also have integers.

JSON Boolean Data Type

JSON objects can also have boolean values. Boolean can have values true or false .

For example, we can write:

{
    "toastWithBreakfast": false,
    "breadWithLunch": true
}

to add them as values.

JSON Null Data Type

The null data type can have the value null .

It is used to represent nothing.

For example, we can write:

{
    "freckleCount": 1,
    "hairy": false,
    "color": null
}

Then we set the value of color to null , which means that no color is set.

JSON Array Data Type

JSON supports array for storing collections of data.

For example, we can write:

{
    "fruits": [
        "apple",
        "orange",
        "grape"
    ]
}

to add the fruits property to an JSON and set the value to an array with the square brackets enclosing the values.

We can add null to an array to add empty values:

{
    "fruits": [
        "apple",
        "orange",
        null,
        "grape"
    ]
}

We can mix and match data types in JSON arrays just like JavaScript arrays.

JSON arrays can have any JSON supported data types in an object.

So we can write:

{
    "scores": [
        92.5,
        62.7,
        84.6,
        92
    ]
}

or

{
    "answers": [
        true,
        false,
        false,
        true,
        false,
        true,
        true
    ]
}

or

{
    "students": [
        "james smith",
        "bob jones",
        "jane smith"
    ]
}

Arrays can also have arrays in them.

For example, we can write:

{
    "tests": [
        [
            true,
            false,
            false
        ],
        [
            true,
            true,
            false
        ],
        [
            true,
            false,
            true
        ]
    ]
}

We add the booleans in an array and then put the arrays in another array outside of it.

JSON Schema

A JSON schema lets us check our JSON for the structure that we expect.

We can validate the conformity of our data with the schema and fix errors that are found.

Validation errors let us fix errors that are found.

This makes us feel confident about the data.

To add a JSON schema to our object, we can write:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Person",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "number",
            "description": "Your person's age in years."
        },
        "gender": {
            "type": "string"
        }
    }
}

We defined the schema object with the $schema property.

Then we have the title to add the title to the schema.

Then we have the properties object with the properties that are allowed in the JSON object that we’re checking against this schema with.

For example, if we have:

{
    "name": "james",
    "age": 20,
    "gender": "male"
}

then that conforms to our schema.

Conclusion

JSON lets us use various data types in our JSON objects.

Also, we can create JSON schemas to validate objects.