Creating a virtual environment in Python

Like in many other languages, Python gives us the possibility to create an environment specific for each project we work on.

Why is this desirable?

If we run many different Python projects inside the same environment, there will be instances where dependencies for different projects will clash with each other and create many other problems.

By keeping each project isolated and create a virtual environment for each one of them, we avoid this problem.

A virtual environment also helps if in the future we need to transfer one particular project to another machine.
By specifying the exact library versions the project runs on, we can recreate the project on any machine exactly as it was specified originally.

Python 3 has a module called venv that can be used to create a virtual environment.

We first create a project directory that will contain all our files and libraries. Inside the project directory we can then use Python 3 to create the virtual environment by running this command:

python3 -m venv .venv

The -m flag calls the venv module as a script.

We then pass a directory name to the venv script, where the environment will be saved.

We name this directory .venv in this case, but it could be called anything.

We prefer to prefix the directory name with a dot, so it won't be shown when we list the files in the project directory.

When we issue the command, the .venv directory will be created and it will include a configuration file called pyven.cfg pointing to the Python version that has created the environment.

The command also creates a bin subdirectory with a symlink to the Python binaries used when we call the python command.

To activate the virtual environment, we need to issue this command:

$ source .venv/bin/activate

We can verify the virtual environment is activated by looking at the modified prompt in our terminal window:

(.venv) $

If we now check which version of Python is active, we see that it's the version specified in the virtual environment:

which python
/.venv/bin/python

If we install or upgrade packages in the virtual environment, they will be installed only inside the virtual environment, and won't affect the default system Python, or any other projects.

To deactivate the virtual environment, we issue the deactivate command at the prompt, and we'll be taken to the regular system shell prompt.

(.venv) $ deactivate
$

If we need to remove the whole virtual environment from a project, we can just delete the .venv directory.

To show all the various options available to the venv command, we can call venv with the -h flag.

python3 -m venv -h

Now that we know how to create a brand new virtual environment we can use it to build awesome Python applications.

Adding a method to a class component

How to pass class component method to child component in React

Sometimes we need to add a method to a class component and pass it down to its child component.
For example, we may have a GroceryList component that has a child component called GroceryItem.
We define a toggleItem() method in GroceryList that we want to trigger from GroceryItem. How do we do that?

Let's first define the method in the parent component.
The way we add a method to a class component is to simply create an identifier inside the class definition and assign an arrow function to it.
The identifier will be the name of the method we call.

class GroceryList extends React.Component {

  toggleItem = itemId => {
    // perform a toggle action
  }

}

To use this method in the child component, we need to pass it down via props:

<GroceryItem item={item} toggleItem={this.toggleItem} />

Inside the child component we then use this method in an onClick event:

<div onClick={ () => {props.toggleItem(props.item.id)} } />
  Click me
</div>

When we click on the <div> element now we trigger the onClick event that will call toggleItem() in the parent component, passing the item id as an argument.

How to add a new item to a list in React

Submit a form and update the application state

If you read the previous articles, you know that at this point in our grocery list application we have a form with an input field and a button.
What we enter in the input field, a grocery item name, is saved in the application state, ready to be added to the array of grocery items already present.
How do we add a new item to the array? We do it with the addGrocery() method.
Let's add the addGrocery() method to our class:

addGrocery = event => {
  // code to add grocery item here
}

When we enter a name in the input field and press the Add button, the first thing that happens is the browser reloads the page. This is the default action a browser takes after submitting a form.

We don't want this behavior, though, we would rather have the list be updated without page refresh, so we use preventDefault() to stop the browser from reloading the page:

addGrocery = event => {
  event.preventDefault();
}

The next thing we want to do is update the state of the application because we are adding something to it.
We update the state with the setState() function and we pass into setState() a new state object that merges what is currently in the state and the new thing we are adding.

So, we first define a newGrocery variable and assign to its name property the value of state.name.
This is the value that is updated by the changeHandler() function that takes its
value from the input field.
We then call setState() passing this new object and add the new grocery item to the state.

let newGrocery = {
  name: this.state.name
}

this.setState(
  { groceries: [...this.state.groceries, newGrocery] }
)

Notice that in React we need to keep the state object immutable, so instead of updating the current state object we set groceries to a new array. We then add the current state to this new array using the spread (...) operator, and finally append the new grocery item at the end of the array.
So, the state gets a brand new array, populated with the current groceries and the new grocery we are adding.

If we now add a new grocery in our web page and submit the form, the new grocery object is added to the end of the array and displayed in the page.

Add one item to a list in React

How to add an item based on user input

In a previous article we learned how to add an input field to a React class component and how to update the state of the component with the value entered in the input field.
Now that we have the value saved in the state we can use it to add a new item to the list of groceries that the component displays.

The user will fill out the grocery item name, press the Return key and the grocery item will be added to the existing list of groceries.

To perform this operation, we could add a button to submit the form, but in this example we take advantage of the default browser behavior of submitting a form automatically when the Return key is pressed.

To take advantage of this behavior we need to add an event listener to the form.
The event listener is called onSubmit and gets triggered when a form is submitted.
onSubmit calls the addGrocery() function which adds the grocery item to the list.
addGrocery() takes as a parameter the content of the name property on the state.
Remember, this property is set to the value of the input field. This is what the user entered.

<form onSubmit={e => {
  this.addGrocery(this.state.name);
}}>

The main purpose of addGrocery() is to take the name of the item and add it to the list. But it also needs to do a couple of other things.

The first thing it needs to do is to stop refreshing the page.
When we submit the form by pressing Return, the browser performs a page refresh by default. We don't want this behavior. We would rather see the item added to the list directly, without a page refresh.

The second thing addGrocery() needs to do is clear out the input field from the grocery name that was typed in so it’s ready for the next input.

To prevent refreshing the page, we use the handy function preventDefault() of the event object. It simply prevents the browser to do the default action.
After adding the grocery item, we also clear out the state name property, so it's brought to its initial state of empty string, by calling setState().
Since the input field displays the value of state.name, it will display an empty string after adding a new item.

Here's the final code:

<form onSubmit={e => {
  e.preventDefault();
  this.addGrocery(this.state.name);
  this.setState({name: ''});
}}>

In the next article we will build the addGrocery() function and complete the functionality.


Did you like this article? Share it with your friends.
I write daily about front-end and back-end web technologies.
You can receive all my articles in your inbox by subscribing to my newsletter. Just click the button below. No spam, just good, useful content. Guaranteed!

Follow me on Twitter

Updating component state in React

How to update class component state from an input field

Sometimes we need to update the state of a component with the value entered into an input field.

An use case would be this:
We have a list of groceries displayed in a view and we need a way to add a new entry in the grocery list.

We have a form field where the user can type in the grocery name and when the enter key is pressed, the new grocery name is added to the existing list.

To do this operation in React we need to update the component state every single time the user enters something in the form field. In turn we need to update the input field at every keystroke to reflect what the content of the state is so far.
This article explains how to set up the component and the input field to achieve this result.

First, let's create an input field in our component:

<form>
  <input
    type="text"
    name="name"
    value={this.state.name}
    placeholder="Enter grocery"
  />
</form>

Note that we set the input type to text, so it will be displayed as a text field by the browser. We also add a name attribute with the value of name and a placeholder text.
We set the value attribute to the value of the name property in the component state, this.state.name.

Let's add the state to our component now:

class Form extends React.Component {
  constructor() {
    super();

    this.state = {
      name: ""
    }
  }
}

As you can see, we set the component state to an object with one property, name, that is initialized to an empty string.
This value will be displayed inside the form field, which will start out as empty.
When the user starts typing inside the form field we want to update the state of our component so the letters typed inside the field are saved in the state.
In order to do this, we need to listen for changes in the input field and call a function that updates the state each time a key is pressed.

Input fields have an onChange event listener that gets triggered every time the field changes. We will use this event listener to update the state.

Let's add the event listener to the input field:

<input
  type="text"
  name="name"
  value={this.state.name}
  placeholder="Enter grocery"
  onChange={this.changeHandler}  // add event listener
/>

The onChange event listener calls the changeHandler() function (that we haven't defined yet) every time the form field changes.
Now we have to define changeHandler() in our component:

changeHandler = event => {
  this.setState({ name: event.target.value });
}

The changeHandler() function is defined inside the class component. It takes an event object as an argument.
The event object is passed to the function by our event listener.

changeHandler() then calls setState() to update the state name property to the current value of the form field.
The event object that is passed in the function has a target property that references the form field. The form field has a value, and the value is whatever the user typed in so far.

So, we use the value in event.target.value to update our name property in the state.
At this point, every time the user types something in the form field, the state is updated and the form field is also updated with the current value of state.name.

We still need a way to update our list with the new grocery name entered, though. We will do this by adding a new function that updates the list.
I will show how to do it in the next article.


Did you like this article? Share it with your friends.
I write daily about front-end and back-end web technologies.
You can receive all my articles in your inbox by subscribing to my newsletter. Just click the button below. No spam, just good, useful content. Guaranteed!

Follow me on Twitter

Loading more posts…