Embracing Context Switching Part One

Chinatown San Francisco

Enable dual language proficiency by studying the differences and similarities between two of the hottest languages: Python and JavaScript.

Developing for the web sometimes requires a number of different skills and languages. The two worlds of JavaScript and Python have found a home in web development but they have their own idiosyncrasies.

Here are some of the more useful features and how they are approached with each language.

Logging and Debugging

JavaScriptPython
console.log("hello");
console.info("This is some info");

console.warn("This is a warning");
console.dir(Object); // Show methods
print("This will log to console")
dir(object) // Show Methods

Unit Testing

JavaScriptPython
Mocha
Chai
Many More…
unittest
Pytest

JavaScript doesn’t come with a native way to test code, but there are a plethora of 3rd party libraries to choose from when you want to make certain your code continues to function. Mocha and Jest are some of the most popular to choose from.

The Python Standard Library on the other hand includes a number of development tools including automatic documentation generation and unit testing to help with developing and maintaining your application.

While unittest is included in the Python, there are 3rd party suites and tools that can help provide better performance and error reporting. Tools like pytest and selenium seek to improve on the experience provided by the built-in testing tools.

Data Types

JavaScriptPython
Boolean, Number, String, Null, UndefinedBoolean, Integer, Float, String, Complex

In JavaScript both null and undefined are primitive data types.

Running the following code:

typeof(null);
typeof(undefined);

JavaScript will respond:

"object"
"undefined"

In Python, complex numbers can be represented using their own data type. A complex number (also known as an imaginary number) is a number whose root is -1.

Using complex numbers is pretty straight forward. Python uses j to represent the imaginary part of the complex number.

my_complex_number = 4+3j
print(type(my_complex_number))

You should see the output:

<class 'complex'>

Exception Handling

JavaScriptPython
try…catchtry … except

The syntax between JavaScript and Python is just different enough to be confusing.

JavaScript will pass in an object with several methods. This can help you to debug the error that has occurred.

try {
   // Try some fancy thing here
} catch (error) {
  // This block is run if an error occurs
  console.warn(error.message)
}

Python’s syntax on the other hand:

try:
  # Try some fancy Python code here
except ValueError:
  # This block runs if a specific ValueError has been encountered
except:
  # This block will run if a different error is thrown

Python allows for many more ways to handle errors. For a more in depth look at error handling in Python check out the docs.

Variables

JavaScriptPython
Declared using let, const, or varAssignment Only

Python and JavaScript handle variable assignment in strikingly different ways though it may not be immediately obvious.

Newer versions of JavaScript allow you to be more selective about where your variables are accessible via the let keyword. let confines the scope of your variable assignments to the block in which it is created.

for(let i=0;i<2;i++){
  let myVar = "Block Scope Variable ";
  console.log(myVar+i);
}
console.log(myVar);
Block Scope Variable 0
Block Scope Variable 1
 /home/justin/Projects/testing/jtest.js:5
   console.log(myVar);
               ^
ReferenceError: myVar is not defined

Using let protects the variables myVar and i from being accessed from outside of the block they were declared. Python on the other hand has no such feature. Python will not prevent you from accessing any values if you really have the desire. Because of this, it’s customary to prefix functions, methods, and variables that are meant to be private using an underscore.

There’s another key difference related to JavaScript’s implicit functionality as well.

Hoisting in JavaScript

JavaScript

console.log(myMessage);
var myMessage = "Hello World!";

Due to hoisting, the code above will work fine and outputs undefined to the console. JavaScript will only hoist variable declarations. As you can see, any assignments that happen will occur where you would expect in your code.

Hoisting also only occurs when using the var keyword. Variables declared using let or const are not hoisted at all and will throw an error myVar is not defined instead of just logging undefined to the console.

Spread and Splat

JavaScriptPython
... (spread)* (splat)

JavaScript and Python have similar tools for unpacking lists or iterables into 0 or more values.

JavaScript Example:

let myList = [1,2];

function myFunc(param1, param2){
  console.log(param1 + param2);
}

myFunc(...myList);

Python Example:

paramList = [1,2]
def addTwo(param1, param2):
  print(param1 + param2)

addTwo(*paramList)

Both of these functions will output the value 3.

Loops

JavaScriptPython
for
for/in
for/of 
while
do/while
while/else

for in
using: range(), enum() and an iterator object.
Array.map()
Array.prototype.forEach()
List Comprehensions
Instead of:
mylist = [1,2,3,4,5]
for x in mylist:
print(x)
Use:
[ print(x) for x in mylist]

There are many ways to create loops in both languages. In addition to C style loops, JavaScript adds additional ways to iterate over arrays, maps, and sets with built in methods which use callbacks.

Functions

JavaScriptPython
function keyworddef keyword
(param1, param2) => expression lambda param1, param2 : expression

JavaScript and Python both allow for multiple ways to declare functions.

The typical way in JavaScript:

function foo(bar1, bar1){
  console.log(bar1 + bar2);
}

and Python:

def foo(bar1, bar2):
  print(bar1 + bar2)

Each can be represented using an anonymous function.

JavaScript: (bar1, bar2)=>console.log(bar1 + bar2);

Python: lambda bar1, bar2 : print(bar1, bar2)

Only JavaScript uses hoisting to allow the invoking of functions before they are declared. Python requires functions to be declared before they’re used.

The implicit behavior particular to JavaScript is that it binds this to different things. this could refer to the local execution context, or it could refer to the invoking functions namespace. Check out this great article describing the different ways JavaScript handles binding this for each of the functions you choose.

Generator Functions

Both JavaScript and Python allow the use of generator functions. These save time and memory when working with large amounts of data by allowing the return of a single value at a time instead of storing copies in memory before returning to the invoking function.

The following is an example of how to use generators in both JavaScript and Python.

JavaScript iterators and generators are explained in detail on MDN.

Hackaday has a great article explaining the difference between iterators and generators in Python.

Conclusion

This is far from an exhaustive list of all the features included in Python and JavaScript but it gives a taste of the subtle differences between the languages. Part Two will cover tools to solve common problems using appropriate language features and data structures.

Using Context in React

Context in React allows you to keep your data compartmentalized in stores.

Along with React 16.8 came a plethora of new features including the ability to subscribe to a central data repository or context. There are many tutorials to follow to learn how to use context, but this one sets out to make it as simple as possible. A repository exists that shows these topics in a working app.

Many of the features available now in React seem similar to features that exist in frameworks like Redux which are frequently built into React applications.

Unfortunately using a data store means that you’ll increase your code complexity slightly but it can have advantages when your application is large enough to require a central data repository for certain values.

High Level Overview

In order to use a data store we’ll need these three things.

  1. Context – The source where the data and its setters reside.
  2. Provider – The class that provides access to the context.
  3. Consumer – This is the class that will get access to the context.

These are the only three things that we need in order to work with contexts.

Create a Context

import React from 'react';

// First we need a new Context
export const CounterContext = React.createContext();

As you can see we can get a new context from the React import. I’m exporting CounterContext because I will be using it later in our counter example.

You may want to put your contexts in a central place in your application. In the demonstration repository I put my context files in src/store.

Create a Provider

// Next we need a provider 
export class CounterProvider extends Component { 
  state = { 
    counter: 0 
  }; 
  render() { 
    return (
      <CounterContext.Provider value={{
        state: this.state,
        addCount: () => this.setState({ counter: this.state.counter + 1 }),        
        subCount: () => this.setState({ counter: this.state.counter - 1 }) 
       }}> 
        {this.props.children} 
      </CounterContext.Provider> 
    ); 
  } 
}

Both the context and the provider should be in the same file above but I have it separated here for clarity. Refer to the repository if you have any questions.

Our provider needs a context to provide to a consumer. The provider requires an attribute named value that will be made available to any consumers of the context.

Fortunately value can be anything and in the code above I have included setters that allow us to easily update our state . There are many ways to approach building applications and certain people may want to use a Store for more complicated projects but that is beyond the scope of this article.

Consume the Values

Next, let’s create our consumer. This is the Counter component created in src/components/Counter.js.

import React from 'react';
import {CounterContext} from '../store/simpleContext';

function Counter(){
  return(
    <div>
      <CounterContext.Consumer>
        {(context)=>(
          <div>
            <p>Count: {context.state.counter}</p>
            <button onClick={context.addCount}>+</button>
            <button onClick={context.subCount}>-</button>
          </div>
        )
        }
      </CounterContext.Consumer>
    </div>
  )
}

export default Counter;

As you can see getting information out of a context is a little more work than getting it from props. First we have to create a consumer from the context we just made ( using CounterContext.Consumer. Then we need to pass the context in as a function parameter to component that will be built.

This is our consumer, but we still need to wrap this component in a provider.

In App.js we use our counter that we made. It is here that we need to wrap Counter in the context provider.

import React from 'react';
import {CounterProvider} from './store/simpleContext';
import Counter from './components/Counter';

function App() {
  return (
    <div className="App">
      <CounterProvider>
        <Counter/>
      </CounterProvider>
    </div>
  );
}

export default App;

At this point you should have everything you need to get context working in React. Unfortunately using context adds more complexity to your project so it’s a design decision that must be made carefully. Having said that, it also allows for a more intuitive flow and compartmentalization of data. If you find that you’re having to pass props around in a deeply nested component tree you may want to think about using context to help you out.

How to Use State in Functional Components in React 16.8

React 16.8 gives developers much more freedom when it comes to functional components.

React 16.8 will change the landscape of React components forever.
React 16.8 will change the landscape of React components forever.

Small and lightweight functional components have only had a subset of the features available to components made with classes. That is until now. In addition to allowing state, functional components have access to the equivalent of component lifecycle methods as well. This allows the same amount of control while requiring less code.

In React 16.8 they added features that functional components have been lacking for quite some time. In addition, more functionality which have been the domain of 3rd party libraries such as Redux, also get baked right in.

This article will take a look at how to use state and lifecycle methods inside functional components to reduce the complexity and repetition of your code. In a later article I will also cover contexts and how to avoid prop drilling. Let’s get started.

State in Functional Components

Prior to React 16.8, if we wanted a component to have state it needed to be written as a class. Now we can use state in functional components as well. First you’ll need to import useState from react.

import React, { useState } from 'react';

useState is a function. This is what we’ll need in order to add state to our functional component.

const [count, setCount] = useState(0);

useState is called with the initial value that state should be set at. In the line above we’re setting our initial count value to 0.

What is returned when we call useState is an array where the first element is the value for state and the second element is a setter for it.

The example above uses Javascript array destructuring to set the state value to count and the setter to setCount.

Using State

When you want to use state you can just reference the value in the state variable you chose. In the above example it is count. You can use it inside the JSX output of your function by simply using the curly braces: {count}

<p>Current Count: {count}</p>

In order to update our count we can just make a call to our setter setCount.

<button onClick={ ()=> setCount(count + 1)}>Change Count</button>

So far an entire functional component with state looks like this:

import React, { useState } from 'react';

function Counter(){
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Current Count: {count}</p>
      <button onClick={()=> setCount(count + 1)}>Change Count</button>
    </div>
  )
}
export default Counter;

Lifecycle Methods in Functional Components

In addition to state, we can also have the same control that we did with all those lifecycle methods only now in our functional components. Because it’s often required to duplicate code across several component lifecycle methods, React developers devised a clever, simpler system to use.

This is where we introduce useEffect.

import React, { useEffect } from 'react';

The way to use this new function may not be entirely obvious at first but I’ll walk through the various ways to use it effectively.

The basic use case is here:

useEffect(()=>{
  // This gets run as you would expect with componentDidUpdate
  // and componentDidMount
})

Call useEffect with the initial value you want your state to be. It takes care of all the code that you would normally put into the compontDidUpdate and componentDidMount methods but instead consolidates it into a single function thereby reducing the amount of code your application needs.

While this may be useful for most of your applications, if you only want to run code when a particular value changes then you can pass in a second parameter — an array with the state to watch. In addition, any stateful values your code needs to access should be passed in this way to ensure that your code has access to the latest value.

useEffect(()=>{
  // This is run only when the values for state that are passed in change.
  // All state used by this function must be passed in together
  // to insure that it is current.
}, [someStateValue, someOtherStateValue])

Cleanup

Sometimes you need to do an action when your component unmounts such as remove listeners. useEffect gives us a way to do this as well.

The function that is passed into useEffect must either return a function or else nothing at all.

The returned function is only called when the component unmounts.

Here’s an example.

useEffect(()=>{
  // This is called when the component updates.
  return ()=>{
    // This anonymous function gets called when the component will unmount.
    // This is where you would remove any listeners etc...
  }
}) 

Additional Features

In addition to adding features to functional components, React 16.8 takes aim at Redux by building within React ways to store state globally that prevent us from needing to prop drill down into deeply nested components.

The next article will go over how to use Context in React to replace the features of Redux.