Monthly Archives: August 2019

React Tips: 4 – Propagating State

One thing that’s worth remembering about React is that when you’re updating state, only the Render method gets re-executed.

It’s easy (as I did) to fall into the trap of doing something like this:

    const myStyle = {
        background: this.props.backgroundFlag == 1 ? "blue" : "yellow",
        display: 'inline-block',
        height: '100%',
    }

    public render() {
        return <>
            <div className="myDiv" style={myStyle}>
        </>
    }

Imagine that this.props.backgroundFlag is actually the state of the containing component; when you change it, you would expect your component to reflect your change. However, in the case above, what will actually happen is nothing – because only the render method is re-evaluated when the virtual DOM changes.

To correct this, you need whatever needs to be re-evaluated inside the render method; for example:

    public render() {
	    const myStyle = {
	        background: this.props.backgroundFlag == 1 ? "blue" : "yellow",
	        display: 'inline-block',
	        height: '100%',
	    }

        return <>
            <div className="myDiv" style={myStyle}>
        </>
    }

UWP using Unity and EF Core and Sqlite

If you intent to use IoC with a UWP application, there are a lot of options. Most of them come with MVVM packages, like MVVM Cross. These are excellent packages – I’ve used MVVM Cross and MVVM Light myself and can highly recommend them.

However, if you didn’t want all that baggage, how would you implement a very simple IoC system in UWP?

In this example, I’m using Unity, however, I believe this will work for any IoC container. I’m also using the IoC container to resolve a View Model – but you don’t need to use View Models (although IMHO, it makes your life so much easier.)

Secondly, I’ll be showing how to use Ef Core with your UWP app. This sounds very trivial, but there’s a bit of fiddling about to get it to work.

Entity Framework Core Set-up

In my project, I’ve separated the data access layer, but you don’t need to do that. Start by creating a data context:

public class MyDbContext : DbContext
{
    public DbSet<Data> MyData { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlite("Data Source=mydata.db");
    }
}

You’ll need the following packages:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.Sqlite

You’ll also need to create a console application – why? Because you can’t use any of the EF tools with UWP! If you set your UWP app as the start-up and create your migration, you’ll get this error:

Startup project ‘SendMessage.UWP’ is a Universal Windows Platform app. This version of the Entity Framework Core Package Manager Console Tools doesn’t support this type of project.

Set the console app as startup and add the migration:

Add-Migration "InitialDbCreate"

Don’t worry about updating the DB, we’ll get the app to do that (it just can’t use the tools, but it can perform a migration.)

UWP

From a new, blank, UWP app; in app.xaml.cs:

sealed partial class App : Application
{
    public static IUnityContainer Container { get; set; } = new UnityContainer();
 
    /// <summary>
    /// Initializes the singleton application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    /// </summary>
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
 
        using (var db = new MyDbContext())
        {
            db.Database.Migrate();
        }
        
        Container.RegisterType<MainViewModel>();
    }

We’re creating a static UnityContainer in App.Xaml.cs. Register the type (in this case a MainViewModel, but it could as easily be an interface).

The next step is resolving the interface. Unfortunately, because of the way that the UWP navigate works, Unity won’t perform constructor injection for us. A little trick around this is to create a parameterless constructor and have that call the injected constructor. It’s not quite constructor injection, but semantically it’s the same thing. Here’s the code from my MainPage.xaml.cs:

public sealed partial class MainPage : Page
{
    public MainPage() : this(App.Container.Resolve<MainViewModel>()) { }
 
    public MainPage(MainViewModel mainViewModel)
    {
        this.InitializeComponent();
 
        this.DataContext = mainViewModel;
    }
}

That’s pretty much it; you can run this, and it’ll migrate the data, and resolve the dependency.

References

https://docs.microsoft.com/en-us/ef/core/get-started/uwp/getting-started

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