Installing and Configuring Redux Form
All right welcome back to the course. In this video we are going to build a signin form component that we will put a grid in and then we'll install redux form and go from there.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So let's go ahead and head over to our signin component, and basically we want to provide a form in here a custom form. So let's go into our auth folder and create a new file and call it signinForm.js and let's import React and build our basic class so import React, from react. Then class SigninForm extends Component render return, let's return a form and lets export it. Now what I'd like to do is give this form a class name of signin form.

sighninForm.js

import React, { Component } from 'react';

class SigninForm extends Component {
  render() {
    return {
      <form className='sign-in-form'>

      </form>
    }
  }
}

export default SigninForm;

Cool, now let's use it in our signin. Let's go in here let's say SigninForm I auto imported it so make sure you import that. And the next thing I'd like to do is basically move our form title into that component. So we're going to have to change it from sign-in to sign-in-form then we're going to have to cut it and throw it into our sign in form.

signin.js

import React, { Component } from 'react';

import { FormTitle } from './signinForm';

import signinForm from './signinForm';

class Signin extends Component {
  render() {
    return (
      <div className='sign-in'>

        <SigninForm/>
      </div>
    )
  }
}

That didn't work, I accidentally opened it up 3 signinForm.js. Basically what I was trying to do was using a command bracket.

signinForm.js

import React, { Component } form 'react';

class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
      </form>
    )
  }
}

export default SigninForm;

Anyway let's go ahead and go to signin.js and you'll see this import FormTitle is broken and thats because we're not using it in here anymore, so let's cut it and put it in signinForm.js. Now I'm going to go ahead and check the package json and see if we have redux form, I don't think we do, all right we don't have it.

So all we need to do is hit command + j to open the terminal and run npm install --save redux-form, Cool, that's going to install and you might get a couple of warnings but that doesn't matter as long as you don't get any errors. So make sure that installs, couple security vulnerabilities we don't need those okay. Let's close our terminal and let's go check our application to see if everything's running, looks good to me still.

large

Now let's just go into our signinForm a put up a couple fields and put that component in and then we will put in the grid and go from there. signinForm let's import and I want to do it up near react. Import and in brackets redux form and field from react-redux

signinForm.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';

import { FromTitle } from '../formTitle';

Class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
      </form>
    )
  }
}

export difault SigninForm;

Excellent, now let's use it by decorating it first so let's say SigninForm at the bottom is equal to reduxForm. And then let's have it take in some parameters specifically just the title. Later on we'll be learning about how to validate these forms, right now it's just going to take a title. So form and the title is sign in that could be anything it just needs to be unique let's put some parentheses here and say SigninForm.

signinForm.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';

import { FormTitle } from '../formTitle';

class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
      </form>
    )
  }
}

SigninForm = reduxForm({
  form: 'signin'
})(SigninForm)

export default SigninForm;

So very similar to how react redux works, how connect works, how we used that in the last set of videos which we'll also be using in this video later on quite a bit, and in this app. So we have that now we just need a field, everything is still running on our website. Just kidding, let's go and check why.

Oh my gosh, okay let's go in here and lets go into console and it says reactRedux.reduxForm is not a function.

large

That's because I imported it from react-redux not redux-form make sure you imported it from redux-form. Okay, now everything should be running good thing we were checking. Let's go ahead and use the Field now, you'll see it's gray because we're not using it. Let's say field and we need to pass it a custom component, okay so that's how field works in redux form.

signinForm.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';

import { FormTitle } from '../formTitle';

class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
        <Field/>
      </form>
    )
  }
}

SigninForm = reduxForm({
  form: 'signin'
})(SigninForm)

export default SigninForm;

So let's develop this component by going into components and let's create a new file and let's just call it formFields.js and we'll have a bunch of things in here, a few classes. For the first one what I want to do is just a form input so lets say import React Component from react and let's try making this a functional component that returns a class.

So let's say export function form input and we will be using state later on but specifically only for an image input. So let's just do this for now, and let's return a class that extends Component. All right, let's type out a render function here and return a div with a class name of form-input. Alright, it should be good there.

Now let's go ahead and let's use it. But first we need to take out some props so we can actually use them in here. So a few things we're going to need are some things like our input name or class name stuff like that.

Okay so let's go into here and in our render let's say constant and what I wanna say is className, title, and name for now let's say that is equal to props. Make sure this is taking in props in the parameter. Excellent, that should be good.

Now what we want to do is put an input in here ok cool. And we're going to want to do in here is give it the className title and name. So let's say class name is equal to and let's use some string interpolation here and say in braces here with a dollar sign class name so we can give it a custom class name so you can place it on a grid. And then let's just say form-input so we can apply some global styles.

formFields.js

import React, { Component } from 'react';

export function FormInput(props) {
  return class extends Component {
    render() {
      const { className, title, name } = props;
      return (
        <div className='form-input'>
          <input className={'${className} form-input'}/>
        </div>
      )
    }
  }
}

Okay, that was kind of a lot of coding but let's see where this puts us when we put one of these on the screen. Okay let's go into signinForm. Field we want to say component is equal to and then our form fields component. So let's import { formInput } from '../formFields'; so were going to take it out and use it. Now in field we just want to say a component is equal to form input, save that and we should be good.

signinForm.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';

import { FormTitle } from '../formTitle';
import { FormInput } from '../formFiends';

class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
        <Field component={FormInput}/>
      </form>
    )
  }
}

SigninForm = reduxForm({
  form: 'signin'
})(SigninForm)

export default SigninForm;

We've got an error and it says name is required in field.

large

So we have to say, and there are going to be a couple more after this too, but we need to say name is equal to and we want to give this a name so let's say, was it user name? Let's check the design. So email, password, and log in. So let's say email and then let's say type is email and then let's give it a class name, and that should be good. Now let's go out and save it and we shouldn't have any errors.

signinForm.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';

import { FormTitle } from '../formTitle';
import { FormInput } from '../formFiends';

class SigninForm extends Component {
  render() {
    return (
      <form className='sign-in-form'>
        <FormTitle className='sign-in-form__title' text='Login'/>
        <Field className='sign-in-form__email' component={FormInput} name='email' type='email'/>
      </form>
    )
  }
}

SigninForm = reduxForm({
  form: 'signin'
})(SigninForm)

export default SigninForm;

Well, we might actually have some because of how we wrote the class, okay so it says functions are not valid as react child. If you return a component instead of component from render or maybe even call this function rather than returning it. Okay, well what I want to do is go into formFields and let's just make a class let's get rid of this export and let's say export class and then what we're going to have to do instead of saying props is this.props. If that doesn't work we'll figure something else out.

Okay, export class extends Component should work. OK and we didn't give a name, so class FormInput and we have another error I just saw. So FormInput and then let's change this retrun to return. Okay export class FormInput we're not exporting it as default so we can take it out the same way were doing with component.

formFields.js

import React, { Component } from 'react';

export class FormInput extends Component {
  render() {
    const { className, title, name } = this.props;
    return (
      <div className='form-input'>
        <input className={'${className} form-input'}/>
      </div>
    )
  }
}

And you'll see in here we have an input now.

large

So this doesn't really mean much to you because I haven't really explained what field and redux-form do, but I can show you what I mean by first throwing in the dev tools.

So let's go into our bootstrap.js and what we want to do is use the compose function from redux. So let's go into this import and let's put a comma and let's say compose and then let's go into createStore here and let's hit command X and then put two pairs of parentheses in here with createStore into one of these and then write compose in front of the first set and then lets wrap both of them in another parenthesis.

It's a little confusing but by doing this we can have access to the dev tools. Let's go ahead and say window dev tools extension question mark and then if it does exist we want to see window.devtoolsExtension and call it like a function and if it doesn't let's just return an empty function and that should be good.

bootstrap.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware()(compose((window.devToolsExtension ? window.devToolsExtension() : f => f)(createStore)));

// import 'bootstrap/dist/css/bootstrap.css';
import './style/main.scss';

import Layout from './components/layout';

import Signup from './components/auth/signup';
import Signin from './components/auth/signin';

function main() {
  ReactDOM.render(
    <Provider store={createStoreWithMiddleware(reducers)}>
      <BrowserRouter>
        <Switch>
          <Layout>
            <Route path='/' exact component={Signin}/>
            <Route path='/signin' component={Signin}/>
            <Route path='/signup' component={Signup}/>
          </Layout>
        </Switch>
      </BrowserRouter>
    </Provider>
    , document.querySelector('.app-wrapper'));
}

document.addEventListener('DOMContentLoaded', main);

So if you've gone through the last video's, or the last applications I show you how to do this. If you're unaware of what this is just google redux dev tools or go back to one of those videos titled redux dev tools in the last set of videos and you'll see what's going on here. Okay, nothing really changed except for now if you go to Google Chrome and go to sign in we still have our input but it doesn't mean much but if right click and then go to Redux Devtools and then go to left you'll see it says init and redux form register field.

large

large

So that's cool. It says email and field right here although we don't really have access to the data. If you go to chart you'll see it's just state and state.

large

So we can really make this effective by basically including in our reducers. So let's go ahead and let's go to our reducers folder and let's go into index.js. Let's get rid of this default state function and we won't be getting that state state anymore. Now it's just state because there's no state function in here anymore. If we were to rename this to asdf and go into here it's going to say state asdf.

large

and that's a function that contains some data. So let's go ahead and put in form from our redux form so let's say import and then lets say reducer as form from redux.

index.js

import { combineReducers } from 'redux';

import { reducer as form } from 'redux-form';

const rootReducer = combineReducers({
  asdf: (state = {}) => state,

});

export default rootReducer;

Okay, a lot of configuration here but it's going to set us up for a lot of cool stuff. Let's get rid of the asdf and say form and that should be working.

index.js

import { combineReducers } from 'redux';

import { reducer as form } from 'redux-form';

const rootReducer = combineReducers({
  form

});

export default rootReducer;

Let's go to our application and here are the results of tools and you'll see now that we have more than just state.

large

We have state we have this fork okay and we have state, form one children count the signin form and registered fields and email so we have email on our one form which is signin when we have a sign up form this form is going to branch into another form which is going to have its own registered fields and its own fields which then contain their own values (name, type, and count).

OK, so let's go ahead and go back to our code. I'm going to close out of index and I'm going to close out of bootstrap and I'm just going to go into FormInput and we are not using title or name. What we want to do is say we want to provide a label here and just put title in here in some braces and then for name we just want to put that on input.

Let's say well we don't need that in here. What we need to do is just this for now.

formFields.js

import React, { Component } from 'react';


export class FormInput extends Component {
    render() {
        const { className, title } = this.props;
        return (
            <div className='form-input'>
                <label>{title}</label>
                <input className={`${className} form-input`}/>
            </div>
        )
    }
}

I'll explain the rest later on because this is getting very long. So right now we have our fields and when you type in the input box on our app, you'll see in the devtools we don't have volume yet.

So let's hop into the next video where we will further develop some redux from fields and I'll see you then.

Terminal

git status
git add .
git commit -m "added redux-form"

I'll see you in the next video.

Resources

Source code