redux-form doesn't get submitted - redux

I have a strange bug in my app. I want to let the user update the name of a group via redux form. Exchanging the old name with the input field works without problem, but when I click on Submit, then nothing happens. This is very strange for me, because I am using the same form to create the group in the first place and there it works totally fine.
import React, { Component } from 'react';
import { connect} from 'react-redux';
import { deleteAccessGroup, editAccessGroup } from '../actions/UserActions';
import { showModal } from '../actions/ModalActions';
import * as types from '../actions/index';
import AccessGroupCreation from '../components/AccessGroupCreation';
class AccessGroupElement extends Component {
constructor(props) {
super(props);
this.state = {
toggle: false
}
}
handleSubmit = values => {
this.props.editAccessGroup(values);
console.log(this.state, "Das sind die values: ", values);
this.edit;
console.log(this.state);
}
edit = () => this.setState({toggle: !this.state.toggle});
delAccessGroup = () => this.props.deleteAccessGroup(this.props.accessGroup.id);
showPicModal = () => {
let id = this.props.accessGroup.id;
this.props.showModal(types.MODAL_TYPE_PICUPLOAD, {
title: 'Please upload a Profile Picture',
onConfirm: (pic) => {
console.log(this.props.accessGroup.id);
console.log( pic)
}
});
}
render() {
const accessGroup=this.props.accessGroup;
return(
<div className="row" id="hoverDiv">
<div className="col-lg-1"></div>
{this.state.toggle ?
<div className="col-lg-9">
<AccessGroupCreation onSubmit={this.handleSubmit} />
</div> :
<div className="col-lg-9">{accessGroup.name}</div>}
<div className="col-lg-2">
<button type="button" onClick={this.delAccessGroup}
className="btn btn-default btn-sm pull-right">
<span className="glyphicon glyphicon-trash"></span>
</button>
<button type="button" onClick={this.edit}
className="btn btn-default btn-sm pull-right">
<span className="glyphicon glyphicon-pencil"></span>
</button>
</div>
</div>
);
}
}
export default connect(null, { deleteAccessGroup, editAccessGroup, showModal })(AccessGroupElement);
Here is the form component:
import React from 'react';
import { Field, reduxForm } from 'redux-form';
const required = value => value ? undefined : 'Required';
const lengthFunction = (min, max) => value =>
value && (value.length > max || value.length < min) ? `Must be between ${min} and ${max} characters` : undefined
const length = lengthFunction(5, 20);
const renderField = ({ input, label, type, meta: { touched, error } }) => (
<div>
<input {...input} placeholder={label} type={type} className="form-control"/>
{touched && (error && <span>{error}</span>)}
</div>
);
const AccessGroupCreation = (props) => {
const { handleSubmit, pristine, submitting } = props;
return (
<form className="form-inline" onSubmit={handleSubmit}>
<div className="input-group">
<Field name="name" type="text"
component={renderField} label="Add an Access Group"
validate={[ required, length]}/>
<span className="input-group-btn">
<button className="btn btn-success" disabled={pristine || submitting}
value="this.state.value" type="submit">
<span className="glyphicon glyphicon-send"></span>
Submit
</button>
</span>
</div>
</form>
)
}
export default reduxForm({
form: 'AccessGroupCreationForm' // a unique identifier for this form
})(AccessGroupCreation)
Help, as always, would be very much appreciated.

Issue is in this code:
handleSubmit = values => {
this.props.editAccessGroup(values);
console.log(this.state, "Das sind die values: ", values);
this.edit; // call this function this.edit();
console.log(this.state);
}

The problem is that your editAccessGroup function isn't tied to your store. Right now, it's creating and returning an action, but that action isn't being dispatched.
The way I'd usually implement it is to use react-redux's connect function and use mapDispatchToProps to bind the actionCreator to your store's dispatch function.

Change few thing as-
...
class AccessGroupElement extends Component {
constructor(props) {
...
}
submit = values => { // rename this function
this.props.editAccessGroup(values);
console.log(this.state, "Das sind die values: ", values);
this.edit;
console.log(this.state);
}
....
render() {
const accessGroup=this.props.accessGroup;
return(
<div className="row" id="hoverDiv">
........
<div className="col-lg-9">
<AccessGroupCreation submit={this.submit} /> // change here
</div> :
.........
</div>
);
}
}
export default connect(null, { deleteAccessGroup, editAccessGroup, showModal })(AccessGroupElement);
then on your form-
const AccessGroupCreation = (props) => {
const { handleSubmit, pristine, submitting, submit } = props; // getting submit function
return (
<form className="form-inline" onSubmit={handleSubmit(submit)}>
.......
</form>
)
}
export default reduxForm({
form: 'AccessGroupCreationForm' // a unique identifier for this form
})(AccessGroupCreation)

Okay, the problem was the use of react-collapsible. It seems like the event handlers "clash", when having redux-form inside/replacing a collapsible. I changed the code and now it works:
<div className="row" id="hoverDiv" key={ accessGroup.id }>
<div className="col-lg-1"/>
{
this.state.toggle ?
<div className="col-lg-9">
<AccessGroupEdit onSubmit={this.handleSubmit} />
</div> :
<div className="col-lg-9">
<Collapsible trigger={accessGroup.name}>
<small><i>Apps:</i></small>
<ul className="list-inline">
{accessGroup.apps.map(group => {
return <li key={group.id}><img width="75px"
height="50px"
src={group.image}
alt={group.name} />
</li>})}
</ul>
<hr />
<small><i>Permissions:</i></small>
<ul className="list-inline">
{Object.keys(accessGroup.permissions).map(permission => {
return accessGroup.permissions[permission] ?
<li key={permission}>
<span className="label label-primary">{permission}</span>
</li> : ""
})}
</ul>
</Collapsible>
</div>
}
<div className="col-lg-2">
<button type="button" onClick={this.delAccessGroup}
className="btn btn-default btn-sm pull-right">
<span className="glyphicon glyphicon-trash"></span>
</button>
<button type="button" onClick={this.edit}
className="btn btn-default btn-sm pull-right">
<span className="glyphicon glyphicon-pencil"></span>
</button>
</div>
</div>

Related

NextAuth with google calendar API, fs module error

so i have a component called cita.jsx where i use the Session Provider as so:
import { useState } from "react";
import { useForm } from "react-hook-form";
import { checkout } from "./checkout";
import { google } from "googleapis";
import { useSession } from "next-auth/react";
import { SessionProvider } from "next-auth/react";
// MUI
import TextField from "#mui/material/TextField";
import { LocalizationProvider } from "#mui/x-date-pickers/LocalizationProvider";
import { AdapterDateFns } from "#mui/x-date-pickers/AdapterDateFns";
import { DateTimePicker } from "#mui/x-date-pickers/DateTimePicker";
import LoginTest from "#/components/loginTest/LoginTest";
export default function Cita({ stripePriceID }) {
// console.log(stripePriceID);
const { register, handleSubmit } = useForm();
const { data: session } = useSession();
const createEvent = async () => {
// Load the Google Calendar API
const calendar = google.calendar({
version: "v3",
auth: session.accessToken,
});
// Create a new event
const event = {
summary: "Test Event",
location: "New York",
description: "This is a test event",
start: {
dateTime: "2023-03-01T09:00:00-07:00",
timeZone: "America/Los_Angeles",
},
end: {
dateTime: "2023-03-01T17:00:00-07:00",
timeZone: "America/Los_Angeles",
},
reminders: {
useDefault: true,
},
};
// Insert the new event
await calendar.events.insert({
calendarId: "primary",
resource: event,
});
};
const [value, setValue] = useState(new Date());
return (
<SessionProvider session={session}>
<div className="flex flex-col justify-center h-[475px] md:h-[555px]">
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DateTimePicker
renderInput={(props) => <TextField {...props} />}
label="Fecha y Hora"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
/>
</LocalizationProvider>
<div
className="overflow-y-auto h-[400px] mt-3
md:scrollbar scrollbar-track-[#d0e7d5] scrollbar-thumb-[#ef8eb2]"
>
<form
onSubmit={handleSubmit(onSubmit)}
className=" flex flex-col space-y-2"
>
<div className=" w-[300px] md:w-[375px] flex flex-col">
<input
{...register("nombre")}
placeholder="Nombre"
className="contactInput"
type="text"
/>
<input
{...register("email")}
placeholder="Email"
className="contactInput"
type="email"
/>
<input
{...register("número")}
placeholder="Número telefónico"
className="contactInput"
type="text"
/>
<input
{...register("medicamentos")}
placeholder="¿Que medicamentos o suplementos consumes?"
className="contactInput"
type="text"
/>
<input
{...register("objectivo")}
placeholder="Objetivo principal"
className="contactInput"
type="text"
/>
<input
{...register("peso")}
placeholder="Peso aproximado"
className="contactInput"
type="text"
/>
<input
{...register("edad")}
placeholder="Edad"
className="contactInput"
type="text"
/>
<input
{...register("estatura")}
placeholder="Estatura promedio"
className="contactInput"
type="text"
/>
<input
{...register("bajar")}
placeholder="¿Por qué quieres bajar de peso?"
className="contactInput"
type="text"
/>
</div>
<LoginTest />
<button
// onClick={() =>
// checkout({
// lineItems: [
// {
// price: `${stripePriceID}`,
// quantity: 1,
// },
// ],
// })
// }
// type="submit"
// role="link"
// className="py-5 px-10 rounded-full text-white bg-[#f28482] font-bold"
>
Pagar Ahora
</button>
</form>
</div>
</div>
</SessionProvider>
);
}
and my logintest: "use client";
import { useSession, signIn, signOut } from "next-auth/react";
export default function LoginTest() {
const { data: session } = useSession();
if (session) {
console.log(session);
return (
<>
Signed in as {session.user.email} <br />
<button onClick={() => signOut()}>Sign out</button>
</>
);
}
return (
<>
Not signed in <br />
<button onClick={() => signIn()}>Sign in</button>
</>
);
}
and then inside my pages/api/auth/[...nextauth].js import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
providers: [
// OAuth authentication providers...
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
],
});
for the life of me, ive been trying to get the calendar api to work with nextjs 13 and i keep getting errors:
i cant seem to figure out how to get this to work. I simply want users, once they authenticate through nextauth, to be able to book an event into my calendar. Please guide me!
./node_modules/gcp-metadata/build/src/gcp-residency.js:19:0
Module not found: Can't resolve 'fs'
Import trace for requested module:
./node_modules/gcp-metadata/build/src/index.js
./node_modules/google-auth-library/build/src/auth/googleauth.js
./node_modules/google-auth-library/build/src/index.js
./node_modules/googleapis/build/src/index.js

Redux State not updating in the Redux DevTool

When I click on a button, it dispatches a function that is meant to login a user and return the user's data. But the Redux store seems not to be updated after the dispatch. When I checked the Redux devtool, It shows that the actions are dispatching appropriately with their payloads but the state remains as the initial state, it doesn't get updated after each dispatched action.
This images below display the action and state of the redux devtool.
Dispatched actions
State display initial state
I don't know I have done wrong, my code are as follows.
userInitialState.js
export default {
user: {},
error: null,
loading: false
};
userLoginAction.js
import axios from 'axios';
import * as types from './actionTypes';
export const signInUserSuccess = payload => ({
type: types.SIGNIN_USER_SUCCESS,
payload
});
export const signingInUser = () => ({
type: types.SIGNING_IN_USER
});
export const signInUserFailure = () => ({
type: types.SIGNIN_USER_FAILURE
});
export const userSignIn = (data) => {
const url = 'https://eventcity.herokuapp.com/api/v1/users/login';
return (dispatch) => {
dispatch(signingInUser());
return axios({
method: 'post',
url,
data
})
.then((response) => {
const user = response.data;
dispatch(signInUserSuccess(user));
})
.catch(() => {
dispatch(signInUserFailure());
});
};
};
userLoginReducer.js
import * as types from '../actions/actionTypes';
import userInitialState from './userInitialState';
const userReducer = (state = userInitialState, action = {}) => {
switch (action.types) {
case types.SIGNING_IN_USER:
return {
...state,
user: {},
error: null,
loading: true
};
case types.SIGNIN_USER_FAILURE:
return {
...state,
user: {},
error: { message: 'Error loading data from the API' },
loading: false
};
case types.SIGNIN_USER_SUCCESS:
return {
...state,
user: action.payload,
error: null,
loading: false
};
default:
return state;
}
};
export default userReducer;
rootReducer.js
import { combineReducers } from 'redux';
import userReducer from './userReducer';
const rootReducer = combineReducers({
userReducer
});
export default rootReducer;
configureStore.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from '../reducer/rootReducer';
const configureStore = () => createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
export default configureStore;
SignInModal.js
import React, { Component } from 'react';
class SignInModal extends Component {
state = {
username: '',
password: ''
};
componentDidMount() {
this.props.userSignIn({});
}
onUsernameChange = e => {
const username = e.target.value;
this.setState(() => ({
username
}));
};
onPasswordChange = e => {
const password = e.target.value;
this.setState(() => ({
password
}));
};
onSubmitForm = e => {
e.preventDefault();
const user = {
username: this.state.username,
password: this.state.password
};
this.props.userSignIn(user);
};
render() {
console.log(this.props.user)
return (
<div>
<div
className="modal fade"
id="exampleModalCenter"
tabIndex="-1"
role="dialog"
aria-labelledby="exampleModalCenterTitle"
aria-hidden="true"
>
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLongTitle">
Sign In Form
</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<form onSubmit={this.onSubmitForm} id="signin">
<div className="form-group">
<label htmlFor="username">Username or Email</label>
<input
type="text"
className="form-control"
name="username"
placeholder="Username or email"
value={this.state.username}
onChange={this.onUsernameChange}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
type="password"
className="form-control"
placeholder="Password"
name="password"
value={this.state.password}
onChange={this.onPasswordChange}
/>
</div>
</form>
<div className="modal-footer">
<button type="button" className="btn btn-secondary" data-dismiss="modal">
Close
</button>
<button type="submit" className="btn btn-primary" form="signin">
Save changes
</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default SignInModal;
SignInModalContainer
import { connect } from 'react-redux';
import { userSignIn } from '../actions/userLoginAction';
import SignInModal from '../components/SignInModal';
const mapStateToProps = state => ({
user: state.userReducer
});
const mapDispatchToProps = dispatch => ({
userSignIn: data => dispatch(userSignIn(data))
});
export default connect(mapStateToProps, mapDispatchToProps)(SignInModal);
I have found the problem. I was using action.types in the switch statement. Instead of using switch(action.type).

Intercept an async action in redux

I'm building a simple notes app using react with redux. My create notes action looks like this:
import axios from "axios";
const URL = 'http://localhost:3002/api/';
export function createNote(data = {}) {
return {
type: 'CREATE_NOTE',
payload: axios.post(URL + 'notes/', data),
};
}
And I've got the following in my reducer:
// Create
case 'CREATE_NOTE_PENDING':
{
return {
...state,
creating: true
};
}
case 'CREATE_NOTE_FULFILLED':
{
return {
...state,
creating: false,
notes: action.payload.data
};
}
case 'CREATE_NOTE_REJECTED': {
return {
...state,
creating: false,
error: action.payload
};
}
And this is my Notes class:
function mapStateToProps(store) {
return {
data: store.note.notes,
fetching: store.note.fetching,
creating: store.note.creating,
error: store.note.error,
};
}
class Notes extends Component {
componentWillMount() {
this.props.dispatch(fetchNotes());
}
create() {
this.props.dispatch(createNote({
title: this.refs.title.value,
content: this.refs.content.value,
}));
this.refs.title.value = '';
this.refs.content.value = '';
}
render() {
return (
<div className="App">
<h1 className="text-center">Notepad</h1>
<div className="row">
<div className="col-md-6 col-md-offset-3">
<div className="form-group">
<input ref="title" placeholder="Create a note" className="form-control" disabled={this.props.creating} />
</div>
<div className="form-group">
<textarea ref="content" className="form-control" disabled={this.props.creating} />
</div>
<button onClick={this.create.bind(this)}
type="submit"
className="btn btn-primary"
style={{float: 'right'}}
disabled={this.props.creating} >Save</button>
</div>
</div>
No on create I'm going to disable the form till I get an answer from the server and reset the content inside the form. My question is how to reset the content of the form when I've got response, i.e. when the form is enabled?
If you want to control the content of input and textarea, you should use controlled components. That is to provide a value attribute to, e.g. input
<input value={this.state.title} placeholder="Create a note" className="form-control" disabled={this.props.creating} />
You can use either internal state or redux state for the value. Then you are able to control the value by setState or redux actions.

Uncaught TypeError when calling an action creator with data from a form input

I am new and would really appreciate your help. I have a form with four inputs (firstName, lastName, position and email) and want to pass the data the user puts in to the state to create an user object. But I always receive this error: Uncaught TypeError: Cannot read property 'firstName' of undefined
Maybe I did map the state wrong? I honestly don't know.
Here is my code:
The form I created which takes the users input:
import React, { Component } from 'react';
import TextField from 'material-ui/TextField';
import { Field, FieldArray, reduxForm} from 'redux-form';
import SelectField from 'material-ui/SelectField';
import MenuItem from 'material-ui/MenuItem';
import validate from './validate';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin(); //Needed, otherwise an error message is shown in the console
//Texteingabefeld
const renderTextField = ({input, label, meta: {touched, error}, ...custom}) => (
<TextField
hintText={label}
floatingLabelText={label}
errorText={touched && error}
{...input}
{...custom}
/>
);
const renderUsers = ({fields, meta: { touched, error }}) => (
<div>
<div>
<button className="btn btn-primary"
type="button" onClick={() => fields.push({})}>
<span className="glyphicon glyphicon-plus-sign"/>Add User
</button>
{touched && error && <span>{error}</span>}
</div>
<Field name="firstName" component={renderTextField} label="First Name"/>
<Field name="lastName" component={renderTextField} label="Last Name"/>
<Field name="position" component={renderTextField} label="Position"/>
<Field name="email" component={renderTextField} label="Email"/>
{fields.map((user, index) =>
<div key={index}>
<Field name={`firstName${index}`} component={renderTextField} label="First Name"/>
<Field name={`lastName${index}`} component={renderTextField} label="Last Name"/>
<Field name={`position${index}`} component={renderTextField} label="Position"/>
<Field name={`email${index}`} component={renderTextField} label="Email"/>
<button className="btn btn-xs btn-danger"
type="button"
title="Remove User"
onClick={() => fields.remove(index)}>
<span className="glyphicon glyphicon-minus-sign"/>
</button>
</div>
)}
</div>
);
const UserCreation = props => {
const { handleSubmit, pristine, reset, submitting} = props;
return (
<form onSubmit={handleSubmit}>
<FieldArray name="users" component={renderUsers}/>
<div>
<button className="btn btn-primary btn-success"
type="submit"
disabled={pristine || submitting}>
<span className="glyphicon glyphicon-send" />
Submit
</button>
{' '}
<button type="button"
className="btn btn-primary btn-danger"
disabled={pristine || submitting}
onClick={reset}>
Cancel
</button>
</div>
</form>
);
}
export default reduxForm({
form: 'UserCreationForm',
validate
})(UserCreation);
The Component which fires the action when the user submits the form:
import React, {Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import UserCreation from '../components/UserCreation';
import { addUser } from '../actions/UserActions';
class UserControlPage extends Component {
componentWillMount() {
}
handleSubmit=(values) => {
addUser(values);
}
render() {
return (
<div>
<legend>
<span className="glyphicon glyphicon-user" aria-hidden="true"></span> User creation
</legend>
<UserCreation onSubmit={this.handleSubmit}/>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({addUser}, dispatch);
}
function mapStateToProps(state) {
return {
users: state.users
}
}
export default connect(mapStateToProps, mapDispatchToProps)(UserControlPage);
The action creator:
import axios from 'axios';
import {ADD_USER} from './index';
export const addUser = (user) => {
return {
type: ADD_USER,
payload: {
// id: id,
firstName: user.payload.firstName,
lastName: user.payload.lastName,
position: user.payload.position,
email: user.payload.email
}
};
}
The reducer:
import {ADD_USER} from '../actions/index';
const INITIAL_STATE = {};
export default function UserReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD_USER:
return [...state, {
// id: action.id,
firstName: action.firstName,
lastName: action.lastName,
position: action.position,
email: action.email
}];
default:
return state;
}
}
The action creator has to get data without the payload, like this:
export const addUser = (user) => {
return {
type: ADD_USER,
payload: {
firstName: user.firstName,
lastName: user.lastName,
position: user.position,
email: user.email
}
}
}
I see a couple things wrong. First of all, you're attaching your data to a payload object inside of your action, but you're not reading from that object in your reducer. So in the reducer, for example, where you have action.firstName, it should actually be action.payload.firstName.
Secondly, what you're returning from the reducer is not right. Your initial state is an object, but you're returning an array. So your state is all kinds of messed up as soon as you mutate state. Try this instead:
import {ADD_USER} from '../actions/index';
const INITIAL_STATE = {};
export default function UserReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD_USER:
return {
...state,
user: action.payload
};
default:
return state;
}
}
Update
I see yet another problem. In this code, you're referencing user.payload, which does not exist.
export const addUser = (user) => {
return {
type: ADD_USER,
payload: {
// id: id,
firstName: user.payload.firstName,
lastName: user.payload.lastName,
position: user.payload.position,
email: user.payload.email
}
};
}
It should be user.firstName, user.lastName, etc.
Thanks guys. Changing the action creator to
export const addUser = (user) => {
return {
type: ADD_USER,
payload: {
firstName: user.firstName,
lastName: user.lastName,
position: user.position,
email: user.email
}
};
}
and the reducer to
const INITIAL_STATE = [];
export default function UserReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case ADD_USER:
return [action.payload, ...state];
default:
return state;
}
}
solved the error.

Getting data from mongo using meteor react

I am just getting started with my project using Meteor/React.
In my "Customer.jsx"
Customer = React.createClass({
propTypes: {
//customer: React.PropTypes.object.isRequired
},
getInitialState: function () {
return { customers: [] };
},
mixins: [ReactMeteorData],
deleteThisCustomer(){
Meteor.call("removeCustomer", this.props.customer._id);
},
getMeteorData() {
let query = {};
//query = {checked: {$ne: true}};
return {
customers: Customers.find(query, {sort: {createdAt: -1}}).fetch()
};
},
handleSubmit(event) {
event.preventDefault();
// Find the text field via the React ref
var data = {};
data['first_name']= ReactDOM.findDOMNode(this.refs.customerFirstName).value.trim();
data['last_name'] = ReactDOM.findDOMNode(this.refs.customerFirstName).value.trim();
console.log(data);
Meteor.call("addCustomer", data);
// Clear form
ReactDOM.findDOMNode(this.refs.customerFirstName).value = "";
ReactDOM.findDOMNode(this.refs.customerLastName).value = "";
},
renderCustomers() {
return this.data.customers.map((customer) => {
return <Customer
key={customer._id}
customer={customer.first_name}
/>
});
},
singleCustomer(){
return(
<li className="customerClassName">
<button className="delete" onClick={this.deleteThisCustomer}>
×
</button>
<label>Here{ this.props.customer }</label>
</li>
);
},
render() {
return (
<div className="container">
<header>
<h1>Add new Customer</h1>
<form role="form" className="form-inline" onSubmit={this.handleSubmit} >
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" ref="customerFirstName" placeholder="First Name." />
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" ref="customerLastName" placeholder="Last Name." />
</div>
<button type="submit" className="btn btn-default">Add Customer</button>
</form>
</header>
<ul>
{this.singleCustomer()}
</ul>
</div>
);
}
});
I keep getting an errors of all sorts every time I try to add first_name or last_name. Matter of fact I think that the whole order and structure of my render() is a nightmare.
Any ideas?
Any help would be appreciated.
Thanks in Advance :)

Resources