Tag Archives: Action

React, Redux, and Typescript – Why, What and How

This article covers adding Redux to an existing React application.

Redux is one of those technologies where you get introduced to it, and you think: this seems overly complex to solve such a simple problem. Quite often, this is, in fact, the case. I once read a post (which I cannot find) by Dan Abramov where he said a similar thing himself. Redux is a state manager, and if you’re using it for React, React does have facilities to manage its own state, so you may not need Redux.

In fact, from what I’ve seen, I’d say you’re better leaving it until you know you need Redux.

Why

So, how will you know when you need Redux?

Well, you’ll know because you’ll raise some state, and suddenly realise that you’ve raised it into a component that has no business managing that state. My specific example was trying to manage user permissions.

Imagine the following menu structure:

Layout.tsx
	NavMenu.tsx
		NavItem (React-Strap)
		LoginMenu.tsx (accesses the DB to get user info)

I needed to store a user permission, and conditionally display a menu option (NavItem); these are held in a LoginMenu component. This meant that my state would need to be in NavMenu.tsx – but that’s a strange place for the state regarding a user to live. Additionally, other parts of the application would need access to this, and so it’s time for a state manager.

What

Okay, we’ve talked about why you might want to add Redux. Let’s see, exactly what Redux is. Essentially, there are three concepts to Redux. Before I continue with my second rate explanation, I would strongly suggest you jump over to Dave Ceddia’s blog. If you’re trying to do this in Typescript, then come back afterwards – otherwise, stay there, there’s nothing I can tell you that he doesn’t cover in this article.

Actions

An action is simply an object that contains a property called type. It can contain other objects, too, and is used to send information from your application into the Redux Store.

Reducers

Reducers are the engine of Redux. They accept an action, and the existing state of the application, and they return a new state.

Store

The store holds the current application state. You cannot change this directly, but through an action.

How

(In this section, I’ll include some imports and file names – I’ll talk about project structure towards the end, and the imports and filenames will make sense then)

Let’s imagine that your application is a game, where you can move a character left and right; your application state might look like this:

export interface IStore = {
    position: 0
}

We’ll also need to create the store, which we can do in the same code file:

Store.tsx

import { reducer } from '../State/Reducer';
import { createStore } from 'redux';

export interface IStore {
    position: number;
}

const store = createStore(reducer);
export default store;

Okay, so we have a state: we said that actions are the only things that can affect state (in fact we said through an action): let’s see what an action might look like:

export const MOVE = 'MOVE'

interface MoveAction {
    type: typeof MOVE
}

This would be sufficient, at least, this is all Redux needs; however, we need to know which way to move, etc. Convention seems to be to add a payload property; let’s see what that might look like:

Actions.tsx

export const MOVE = 'MOVE'
export interface Message {
    user: string
    message: string
    timestamp: number
  }
  
interface MoveAction {
    type: typeof MOVE
    payload: Message
}
    
export type ActionTypes = MoveAction;

I’ve used a generic Message – you could make this specific to your action, but this sort of approach means that your messages are consistent across actions.

So, now we have a store (somewhere to keep the state), and an action something to indicate that we wish to update the state. However, looking at the action, it doesn’t seem to do too much updating… In fact, it’s just a message – it could even be just a string. We now need the final piece of the jig-saw: the reducer takes the action and updates the state; let’s see what that might look like:

Reducer.tsx

import { InitialState } from './Store';
import { ActionTypes, MOVE } from './Actions';

export function reducer(state = InitialState, action: ActionTypes) {  
    console.log (action);
    switch (action.type) {
      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }
        
      default:
        return state;
  
    }
    
}

There’s quite a lot here: (we’ll come back to InitialState shortly). Let’s go through a piece at a time.

The first thing we’re doing is checking the type parameter:

    switch (action.type) {
      case MOVE:

In a real world situation, there would be many options: you’re unlikely to have a single action, so the switch statement is necessary.

Remember earlier, we defined the action as MOVE:

export const MOVE = 'MOVE'

Which enables us to check for MOVE, rather than the magic string “MOVE”.

Inside the MOVE block, we’re accessing the payload:

      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }

The reducer must be a pure function: that is, it accepts and returns data, but it does not change anything; as a result, we’re returning a new version of the state that was passed in. We’re setting the new state to have a position which is based on the current position, but we’re not changing the state.

This code will crash if the message is set to “qwerty” (so if you’re doing this sort of thing yourself, you should do it better than I have!)

Finally, the default: block simply returns the same state that it was given; i.e. the state remains unchanged.

Initial State and Project Structure

I said we’d come back to initial state. In the reducer, we have the following:

export function reducer(state = InitialState, action: ActionTypes) {  

We have to define a starting state for the store; and you can do that like this:

Store.tsx

export const InitialState: IStore = {
    position: 0
}

Before we move onto the application changes, let’s quickly talk about where this all goes. The frustrating answer is, it’s up to you; however, I found a structure like this quite useful, as it keeps all the Redux plumbing in a single place:

Plugging this into your app

So far, we’ve created a lot of code, but it’s been completely separate from your React application. Plugging it in is actually quite trivial. Let’s start with Index.tsx; you’ll need to import your reducer:

import { reducer } from './State/Reducer';

In the render function, you’ll then need to add the store into the DOM:

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter basename={baseUrl}>
      <App />
    </BrowserRouter>
  </Provider>,
  rootElement);

We can then access the store inside any component by simply referencing the Store.tsx:

import store from '../../State/Store';
import { MOVE } from '../../State/Actions';

And then calling the dispatch function:

            store.dispatch({
                type: MOVE,
                payload: {
                    user: user.name,
                    message: "1",
                    timestamp: new Date().getTime()
                }
            });

We can also get the state by using this:

store.getState();

Connecting the State

This works okay, but there is an easier way; you can use the Redux Connect function. Essentially, instead of exporting the React class, you instead export a wrapper for it. Before that, though, you need to work out what you’re trying to map. You’ll need to split your props into three groups:

1. Props from the store that you want in your component
2. Props that you want to be passed into your component
3. Props from the store that are actually functions; that is, dispatch functions

You would then rewrite your component like this:

import { connect } from 'react-redux';
interface StoreProps {
   position: number;
}
interface OwnProps {
   ...
}
interface DispatchProps {
   ...
}

type Props = OwnProps & StoreProps & DispatchProps;
interface IState {
   ...
}
class GameComponent extends Component<Props, IState> {
   ...

Notice that you’re no longer exporting the GameComponent class. Instead, you add the following:

function mapStateToProps(state: IStore) {
  return {
    position: state.position
  };
}
export default connect(mapStateToProps)(GameComponent);

This allows you to expose only the properties relevant to the component, but not the properties that you take from the Redux store.

References

https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835/

https://daveceddia.com/redux-tutorial/

https://daveceddia.com/access-redux-store-outside-react/

https://redux.js.org/recipes/usage-with-typescript

Testing for Exceptions using the Arrange Act Assert Pattern in C# 7

Unit testing massively benefits from following the Arrange / Act / Assert pattern. I’ve seen tests that are not written in this way, and they can be sprawling and indecipherable, either testing many different things in series, or testing nothing at all except the .Net Framework.

I recently found an issue while trying to test for an exception being thrown, which is that Nunit (and probably other frameworks) test for an exception by accepting a delegate to test. Here’s an example:

        [Test]
        public void Test_ThrowException_ExceptionThrown()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act / Assert
            Assert.Throws(typeof(Exception), tc.ThrowException);
        }

We’re just testing a dummy class:

    public class TestClass
    {
        public void ThrowException()
        {
            throw new Exception("MyException");
        }
    }

C# 7 – Inline functions

If you look in the references at the bottom, you’ll see something more akin to this approach:

        public void Test_ThrowException_ExceptionThrown2()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            TestDelegate throwException = () => tc.ThrowException();            

            // Assert
            Assert.Throws(typeof(Exception), throwException);
        }

However, since C# 7, the option on a local function has arrived. The following has the same effect:

        [Test]
        public void Test_ThrowException_ExceptionThrown3()
        {
            // Arrange
            TestClass tc = new TestClass();

            // Act
            void CallThrowException()
            {
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

I think that I, personally, still prefer the anonymous function for this; however, the local function does present some options; for example:

        [Test]
        public void Test_ThrowException_ExceptionThrown4()
        {
            void CallThrowException()
            {
                // Arrange
                TestClass tc = new TestClass();

                // Act
                tc.ThrowException();
            }

            // Assert
            Assert.Throws(typeof(Exception), CallThrowException);
        }

Now I’m not so sure that I still prefer the anonymous function.

References

http://stackoverflow.com/questions/33897323/nunit-3-0-and-assert-throws

https://pmbanugo.wordpress.com/2014/06/16/exception-testing-pattern/

http://stackoverflow.com/questions/24070115/best-approach-towards-applying-the-arrange-act-assert-pattern-when-expecting-exc

Working with the threading system in Unity

Unity seems to have a multi-threaded system, but I could find no way of accessing the dispatcher. Consequently, it’s necessary to create some kind of self-rolled task queue. The specific problem that I faced was with using the timer; here’s the code for the timer:

public class MasterScript : MonoBehaviour
{
    private Timer _timer;

    void Start ()
    {
        _timer = new Timer();
        _timer.Interval = 1000;
        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
    }

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }
}

The idea being that every second, and new object would appear on the screen. However, as soon as you run this, it crashes (or as close as Unity comes to crashing):

FindGameObjectWithTag can only be called from the main thread

The solution that I came up with was as follows:

public class MasterScript : MonoBehaviour
{
    public static Queue<Action> TaskQueue;

    private void _timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        SpawnNewObject();
    }

    private void SpawnNewObject()
    {
        TaskQueue.Enqueue(() =>
        {
            var newObj = Instantiate<GameObject>(MyObject);

Then, simply change the Update function to run them:

    void Update ()
    {
        if (TaskQueue.Count > 0)
        {
            TaskQueue.Dequeue().Invoke();
        }
    }

I’ve used the idea of a “Master Script” to deal with the queue, and this can be queued to from somewhere else in the game, which makes it more flexible.