Tag Archives: React

React Tips: 3 – Cloning a React Repository

After you clone a React repository, running npm start may give this error:

‘react-scripts’ is not recognized as an internal or external command

The reason, as explained here, is that you need to run:

npm install

This should be run inside the directory that you clone. For example:

git clone https://github.com/pcmichaels/react-demos.git
cd react-demos
npm install
npm start

React Tips: 2 – Binding an Event Handler

Example code here.

When dealing with any flavour of Javascript, sooner or later, you’re going to come across the this problem. The issue being that, what this means, depends on where you are. This can be a particularly prevalent issue with React; imagine the following code:

onMouseUp={this.onMouseUp}

In onMouseUp, you might want to affect the state in some way:

private onMouseUp(e) {
    this.setState({
        dragging: false
    });

If you run this, you’ll likely get the following error:

TypeError: this is undefined

I think you’ll agree, a clearer message couldn’t be had.

Binding

The answer to the problem that I’ve so eloquently posed here, is binding. Essentially, you simply tell your local function to know about this:

onMouseUp={this.onMouseUp.bind(this)}

This does fix the problem; now the method will execute without error. However, what we are actually doing here is creating a new function every time the page is rendered. To circumvent this you can leave the original code as it was:

onMouseUp={this.onMouseUp}

But then bind the method in the constructor:

constructor(props) {
    super(props);

	this.onMouseUp = this.onMouseUp.bind(this);

As an aside, if you happen to see the following error:

Argument of type ‘this’ is not assignable to parameter of type ‘MouseEvent‘.

You’ve likely missed the .bind; for example:

this.onMouseUp = this.onMouseUp(this);

Ask me how I know!

Class Properties

Another, newer (and IMHO much cleaner), way around this is the following syntax:

onMouseDown = (e) => {
    console.log('onMouseDown');
    this.setState({
        dragging: true
    });
}

This doesn’t require any binding.

References

https://reactjs.org/docs/faq-functions.html

A C# Developer’s Guide to: ReactJS – Part 3 – Conditionally Rendering HTML in React

This is the third in a series of posts on interesting things I’ve discovered about React; the first of these can be found here.

One of the things that tripped me up early on while I was learning React (not that I’m a fully-fledged expert now or anything) was how to display HTML elements based on a given criteria. For example, say you only want to display a label while the form is loading, or you want to display a message based on other information on the screen.

If you were using a desktop binding architecture, say MVVM, you would bind the visibility to a visible property. Likewise in HTML, you may have a conditional style based on the bound model property. Let’s see how you might do that in React.

Create a new React Application

Let’s start by creating a new React application (using bash here):

This isn’t a particularly fast process, so maybe it’s time to get a brew.

Once it’s done, and assuming you have VS Code installed (if you don’t then go and install it from here), type:

code testreactapp

And as if by magic, VS Code appears!

You should be able to run this straight out of the box. Start a new terminal in VS Code, and type npm start:

The displayed screen is of a little animated spiragraph. Let’s add a button and, where the user presses the button, hide or show the spinning spiragraph.

State

As I have previously written about here state is one of the key concepts in React. Let’s create a state object that will determine the visibility of our animation.

In order to introduce state, we need to change the default app.js to be a class, as functions cannot have state. Note that, were this a real application, you would probably move this out into a separate component; but let’s change our app.js to be a class:

import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';

export default class App extends Component {
	render() {
		return (
			<div className="App">
				<header className="App-header">
					<img src={logo} className="App-logo" alt="logo" />
					<p>
						Edit <code>src/App.js</code> and save to reload.
					</p>
					<a
					className="App-link"
					href="https://reactjs.org"
					target="_blank"
					rel="noopener noreferrer"
					>
						Learn React
					</a>
				</header>
			</div>
		);
	}
}

All I’ve done here is change the function to a class, and added `import {Component}`.

Now let’s add some state. At the top of the class, add a constructor:

constructor(props) {
	super(props)
	this.state = {
		showSpiragraph: true
	}
}

Let’s now add the button, so we can change the value of the state; first, we’ll need the button itself:

. . .
	<a
		className="App-link"
		href="https://reactjs.org"
		target="_blank"
		rel="noopener noreferrer"
	>
		Learn React
	</a>
	<button onClick={this.toggleShow}>Hide/Show</button>
</header>
. . .

Then the function that we’re calling (toggleShow):

toggleShow = () => {
  this.setState(state => ({showSpiragraph: !state.showSpiragraph}));
}

If you run this now, it will allow you to press the button until your finger aches, but it won’t actually do anything.

Conditionally Displaying an Element

Okay, so we come to the crux of the entire post; we can conditionally render our image by using the following syntax:

. . .
<header className="App-header">
  {this.state.showSpiragraph &&
    <img src={logo} className="App-logo" alt="logo" />
  }
. . .

You should now be able to click the button and have the Spiragraph show and hide at will.

References

https://medium.freecodecamp.org/quick-guide-to-understanding-and-creating-reactjs-apps-8457ee8f7123

https://reactjs.org/docs/handling-events.html

A C# Developer’s Guide to: ReactJS – Part 2 – Moving Controls

Following on from my previous post, I’m going to extend our ReactJS application by adding some boxes, and allowing the user to re-arrange them on the screen.

Concepts

There are two key concepts to consider when working with React, and we’ll cover one of them in this post; that is: state.

React has a special property of each component known as state. If you use that to bind any of the UI to, then React will refresh that component when the state changes.

Moving a UI Element

Okay – that sounds great, but how would we do this in practice?

Imagine that you have a HTML box drawn on the screen; you might have something like this:

<div style="height:100px; width:200px; background:#0000FF" />

We can draw a box. If you use this code, then your box will be on the top left of the screen; so we can tell it not to be by specifying the left and top; let’s try defining a CSS style:

<div style="left:10px; top:20px;height:100px; width:200px; background:#0000FF" />

With React, we can set those values to a value derived from the state; for example:

render() {
    const top = this.state.newY;
    const left = this.state.newX;

    const myStyle = {
        height: '100px',
        width: '200px', 
        top: `calc(${top}px)`,
        left: `calc(${left}px)`, 
        borderStyle: 'solid',
        borderColor: 'blue', 
        position: 'absolute',
        zIndex: 1,
        background: 'blue'
    };

    return ( 
        <div> 
            <div style={myStyle}>source</div>
        </div>
    );
}

What this means is that every time I change the state values, the values in the style will update.

To illustrate this, if we write a React application like this (only the timeout function is new):

render() {
    const top = this.state.newY;
    const left = this.state.newX;
    const myStyle = {
        height: '100px',
        width: '200px', 
        top: `calc(${top}px)`,
        left: `calc(${left}px)`, 
        borderStyle: 'solid',
        borderColor: 'blue', 
        position: 'absolute',
        zIndex: 1,
        background: 'blue'
    };

    setTimeout(() => {
        this.setState({newX: this.state.newX + 1, newY: this.state.newY + 1});
    }, 50);

    return ( 
        <div> 
            <div style={myStyle}></div>
        </div>
    );
}

We can make out box move diagonally across the screen:

Screenshot included because you couldn’t possibly imaging what a blue rectangle looks like.

Start the app using VS Code

A quick note on VS Code. If you select Terminal -> New from the menu, you can run the React application directly from the IDE; and the best part is that if there’s something already running on the port, VS Code will just give you a new one:

Short Walks – Navigating in ReactJs

When you start using the React sample templates, one thing that you’ll notice is the navigation menu; it tends to look like this:

<div className='navbar-collapse collapse'>
    <ul className='nav navbar-nav'>
        <li>
            <NavLink to={ '/' } exact activeClassName='active'>
                <span className='glyphicon glyphicon-home'></span> Home
            </NavLink>
        </li>

After messing around for a while, you’ll probably think: now I need to navigate somewhere from within the code of the tsx/jsx file. Turns out you need to use `.push()`:

import { NavLink } from 'react-router-dom';

. . .

doSomething()
.then(output => {
    this.props.history.push('/timbuktu');
});

Not exactly intuitive. And even less intuitive is if you want to go back. You’re thinking it must be `.pop()`? So was I; it’s actually:

import { NavLink } from 'react-router-dom';

. . .

doSomething()
.then(output => {
    this.props.history.goBack();
});

Adding ReactJS to an existing Asp.Net Core 2 Application

I’ve recently been playing around with writing an Asp.Net Core 2 app from scratch. If you’re interested, you can view my exploits here.

I came across an interesting issue, which was that I wanted to search an in memory set of data, and I wanted the screen to update as I searched. React sounds like the perfect tool for this; and this article describes how to integrate a React view (JSX file) into an MVC view.

(Note that it doesn’t cover implementing the search function – that will be the subject of a later post when and if I work out how to do it.)

Set-up

After you’ve created your Asp.Net Core 2 application, the first step is to install React; which is a NuGet package:

Install-Package React.AspNet -Source nuget.org

There are some code tweaks that are needed; the first is in startup.cs (which basically tells Asp to use React, and how to do so):

services.AddTransient< …
 
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddReact();
 
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
app.UseReact(config =>
{
    
});
 
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

You’ll need to slightly change the signature of ConfigureServices, too:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
. . . 
    return services.BuildServiceProvider();
}

The next thing is to make React available to your views; in ViewImports.cshtml:

@using UsefulSites.Web
@using UsefulSites.Web.Models
@using UsefulSites.Web.ViewModels
@using React.AspNet
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

React Code

Next step is to create the ReactJs file:

class SearchBox extends React.Component {
    render() {
        return (
            <div className="search-container">
                <textarea>
                    Search Text
                </textarea>    
            </div>
        );
    }
}
 
ReactDOM.render(
    <SearchBox />,
    document.getElementById('content')
);

Then change the HTML file:

<div class="row">
    <div class="jumbotron">
        <div id="content"></div>
        <script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.development.js"></script>
        <script crossorigin src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.development.js"></script>
        <script src="@Url.Content("~/js/search.jsx")"></script>
    </div>

As you can see, the React script references the div named “content” specifically.

References

https://reactjs.net/getting-started/aspnetcore.html

https://reactjs.net/getting-started/download.html