Crud actions on input set - react+flux+alt+es6 - reactjs

I am new to react.In my application I have to perform crud action on inputset(contains one selectbox and textarea) within form.Form loads with one inputset with default values.
Actions
Onchange of inputset text it should update state if not it should
store with default values.
OnAdd it should check previous element has not empty description.
Paricular inputSet should be removed and on clearing description
also it should remove that inputSet
Image:
Code:
Item
import React from 'react';
import { Input, Button, Glyphicon } from 'react-bootstrap';
export default class TextBoxesSet extends React.Component {
constructor(props) {
super(props);
}
_onRemoveName = () => {
console.log('remove');
}
static getPropsFromStores() {
return {language: 'en', description: ''};
}
render() {
return (
<div >
<div className="">
<Input type="select" placeholder="select" wrapperClassName="col-xs-4"
value={this.props.language} onChange={this.handleChange.bind(this, 'language')} >
<option value="en">en</option>
<option value="de">de</option>
</Input>
</div>
<div className="col-md-7">
<Input type="textarea" wrapperClassName="col-xs-12" value={this.props.description}
onChange={this.handleChange.bind(this, 'description')} />
</div>
<div className="col-md-1">
<Button bsSize="small"><Glyphicon glyph="remove" onClick={this._onRemoveName} /></Button>
</div>
</div>
);
}
handleChange(name, e) {
const obj = {};
obj[name] = e.target.value;
this.setState(obj);
if (this.state.language !== undefined && this.state.description !== undefined) {
this.props.handleChange('name', this.state);
}
}
}
TextBoxesSet.propTypes = {
language: React.PropTypes.string,
description: React.PropTypes.string,
handleChange: React.PropTypes.func
};
List
import React from 'react';
import { Button, Glyphicon } from 'react-bootstrap';
// import TextBoxStore from 'stores/textBoxStore';
import TextBoxesSet from './descriptionTextBoxes';
export default class TextBoxesSetList extends React.Component {
constructor(props) {
super(props);
}
_onAddName = (label) => {
if (this.state) {
this.state[label].length++;
React.render(<TextBoxesSet labelName="name" language="de" handleChange={this.handleTextBoxSetChange}/>, document.getElementById('another'));
}
}
_onRemoveName = () => {
console.log('remove');
}
render() {
return (
<div >
<ul >
<TextBoxesSet label={this.props.labelName} handleChange={this.props.handleChange}/>
</ul>
<div className="col-md-1">
<Button bsSize="small"><Glyphicon glyph="plus" onClick={this._onAddName} /></Button>
</div>
</div>
);
}
}
TextBoxesSetList.propTypes = {
newItem: React.PropTypes.string,
list: React.PropTypes.array,
labelName: React.PropTypes.string,
handleChange: React.PropTypes.func
};
Form
import React from 'react';
import { Input, Button, Glyphicon, ButtonToolbar } from 'react-bootstrap';
import AttributeSectionStore from 'stores/attributeSection/AttributeSectionStore';
import TextBoxesSetList from '../TextBoxesList';
import styles from 'scss/_common';
export default class Name extends React.Component {
constructor(props) {
super(props);
this.handleTextBoxSetChange = this.handleTextBoxSetChange.bind(this);
}
_onCreate = () => {
console.log('___________', this.state);
}
static getPropsFromStores() {
return AttributeSectionStore.getState();
}
render() {
return (
<div className="container">
<div className={styles.mainheader}>
<h2 >New Form</h2>
</div>
<div className="col-md-9">
<form className="form-horizontal">
<div className="row">
<div className="col-xs-2">
<label className="">Name</label>
</div>
<div className="col-md-6">
<TextBoxesSetList labelName="name" handleChange={this.handleTextBoxSetChange}/>
</div>
</div>
</form>
</div>
</div>
);
}
handleChange(name, e) {
const change = {};
change[name] = e.target.value;
this.setState(change);
}
handleTextBoxSetChange(label, obj) {
const change = {};
if (this.state[label] === undefined) {
console.log('--------------------');
change[label] = [];
change[label].push(obj);
}
this.setState(change);
}
}
Name.propTypes = {
name: React.PropTypes.arrayOf(React.PropTypes.object)
};
Please help me in solving?

Related

React Component not reflecting current state of store

I have implemented a component that shows courses. Within the same component, there is functionality for filtering courses when a user searches for a certain course.
The problem I am having is when I dispatch an action for filtering courses, the redux store shows the courses state has been updated to contain only courses that match the search query but the component does not reflect the new state(i.e still shows all courses). How can I resolve this issue?
Here is what I have implemented so far
Action
export const retrieveAllCourses = (url, query) => dispatch => {
return axios
.get(url + `?title=${query}`, {
headers: myHeaders
})
.then(res => {
const fetchall = {
type: ACTION_TYPE.VIEW_COURSES,
payload: res.data.courses
};
dispatch(fetchall);
})
.catch(error => {
toast.error(error, { autoClose: 3500, hideProgressBar: true });
});
};
Reducer
import ACTION_TYPE from "../../actions/actionTypes";
const initialState = {
courses: [],
};
const coursesReducer = (state = initialState, action) => {
switch (action.type) {
case ACTION_TYPE.VIEW_COURSES:
return {
...state,
courses: state.courses.concat(action.payload.results),
};
default:
return state;
}
};
export default coursesReducer;
Search component
import React from "react";
import PropTypes from "prop-types";
class Search extends React.Component {
state = {
search: ""
};
handleChange = ev => {
ev.preventDefault();
const { onChange } = this.props;
const search = ev.target.value;
this.setState({ search });
if (onChange) {
onChange(search);
}
};
handleSearch = ev => {
ev.preventDefault();
const { onSearch } = this.props;
const { search } = this.state;
if (onSearch) {
onSearch(search);
}
};
render() {
const { id } = this.props;
window.onload = function() {
var input = document.getElementById("search-input");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("mySearchBtn").click();
}
});
};
return (
<React.Fragment>
<form id={id}>
<div className="search-container">
<div className="input-group">
<input
type="text"
id="search-input"
className="search-input form-control"
placeholder="Search lessons"
onChange={this.handleChange}
/>
</div>
<div>
<button id="mySearchBtn" onClick={this.handleSearch} />
</div>
</div>
</form>
</React.Fragment>
);
}
}
Search.propTypes = {
onChange: PropTypes.func,
onSearch: PropTypes.func,
id: PropTypes.number
};
export default Search;
Navbar component
import React from "react";
import PropTypes from "prop-types";
import Search from "../../components/courses/Search";
export const LoggedInNavBar = ({ handleSearch, handleSearchChange}) => {
return (
<div className="row bobo-menu">
<div className="col-sm">
<div className="logo-container">
<a href={"/courses"}>
<h1 id="logo" className="hidden">
TUTORIALS
</h1>
</a>
</div>
</div>
<div className="col-sm">
<Search onSearch={handleSearch} onChange={handleSearchChange} />
</div>
<div className="col-sm">
<p id="motto">
TUTORIALS<span className="text-succes"> AND</span> LEARNING{" "}
<span className="text-succes">FOR ALL</span>
</p>
</div>
<div className="col-sm">
<div className="row row__menu__icons">
<div className="col-lg-3 col-md-3 col-sm-3">
<a
id="title"
href="/create"
className="btn btn-login "
data-mode="signin"
>
{" "}
<i className="fas fa-plus" />
</a>
</div>
<div className="col-lg-3 col-md-3 col-sm-3">
<a
id="title"
href="/create"
className="btn btn-login "
data-mode="signin"
>
<i className="far fa-user" />
</a>
</div>
<div className="col-lg-3 col-md-3 col-sm-3">
<a
id="title"
href="/me/stories"
className="btn btn-login "
data-mode="signin"
>
<i className="fas fa-book" />
</a>
</div>
<div className="col-lg-3 col-md-3 col-sm-3">
<a
id="title"
href="/create"
className="btn btn-login "
data-mode="signin"
>
<i className="fas fa-sign-out-alt" />
</a>
</div>
</div>
</div>
<br />
<br />
</div>
);
};
LoggedInNavBar.propTypes = {
handleSearch: PropTypes.func,
handleSearchChange: PropTypes.func
};
Courses component
import React, { Fragment } from "react";
import { details } from "../../routes/protectedRoutes";
import { AUTHENTICATED } from "../../utils/myHeaders";
import { ViewAllCourses } from "../../views/courses/viewSearchResults";
import { retrieveAllCourses } from "../../actions/courseActions/courseAction";
import { LoggedInNavBar } from "../navigation/LoggedIn";
import { API_URLS } from "../../appUrls";
import PropTypes from "prop-types";
import { connect } from "react-redux";
export class Courses extends React.Component {
constructor(props) {
super(props);
this.user = details(AUTHENTICATED);
this.state = {
search: ""
};
}
componentDidMount() {
this.fetchCourses();
}
fetchCourses = (searchStr = null) => {
let Url = API_URLS.FETCH_CREATE_ARTICLES;
const { search } = this.state;
const query = searchStr !== null ? searchStr : search;
this.props.dispatch(retrieveAllCourses( Url, query ));
};
handleSearch = search => {
this.setState({ search });
this.fetchCourses(search);
};
handleSearchChange = search => {
if (!search) {
this.setState({ search });
this.fetchCourses(search);
}
};
render() {
const { allCourses } = this.props;
return (
<div>
<LoggedInNavBar
handleSearchChange={this.handleSearchChange}
handleSearch={this.handleSearch}
/>
<ViewAllCourses results={allVideos} />
</div>
);
}
}
Courses.propTypes = {
dispatch: PropTypes.func.isRequired,
allCourses: PropTypes.array
};
const mapStateToProps = state => ({
allCourses: state.coursesReducer.courses
});
const mapDispatchToProps = dispatch => ({ dispatch });
export default connect(
mapStateToProps,
mapDispatchToProps
)(Courses);
API response
In your reducer, why are you concatenating it with previous state results? Your filtering will never show associated data if you're doing this.
I see no payload.results in your action dispatch. Shouldn't it be action.payload & not action.payload.results?
return {
...state,
courses: action.payload,
}
There's no state variable called videos in your reducer. You're dispatching & storing courses, so you have to listen to:
const mapStateToProps = state => ({
allCourses: state.coursesReducer.courses
});
Hope this is helpful!

React Component array not updating

I'm learning react, and I'm stuck with not updating list components.
The component shows all of the list elements that I add manually, but not rendering any changes.
I searched a lot for solutions.
All of my change handlers are binded, the setState inside handleSubmit should update ClockRow...
My App.js:
import React, { Component } from 'react';
import Clock from './Clock';
import ClockRow from './ClockRow';
class App extends Component {
constructor(props) {
super(props);
this.state = {items: [], tle: 'Teszt', ival: 200};
this.handleChangeTitle = this.handleChangeTitle.bind(this);
this.handleChangeInterval = this.handleChangeInterval.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeTitle(event) {
this.setState({tle: event.target.value});
}
handleChangeInterval(event) {
this.setState({ival: event.target.value});
}
handleSubmit(event) {
if(this.state.tle.length > 0 && this.state.ival > 9){
this.setState({items: [...this.state.items, <Clock interval={this.state.ival} title={this.state.tle} />]});
}
event.preventDefault();
}
render(){
return (
<div>
<div className="row">
<h1 className="col text-center">Hello, React!</h1>
</div>
<div className="row">
<form onSubmit={this.handleSubmit}>
<label>
Title: <input type="text" name="tle" value={this.state.tle} onChange={this.handleChangeTitle} />
</label>
<label>
Interval: <input type="number" name="ival" value={this.state.ival} onChange={this.handleChangeInterval} />
</label>
<input type="submit" value="Add" />
</form>
</div>
<ClockRow clockItems={this.state.items} />
</div>
);
}
}
export default App;
My ClockRow.js:
import React, { Component } from 'react';
class ClockRow extends Component{
constructor(props){
super(props);
this.state = {clocks: props.clockItems.map((x, i) => <div className="col" key={i}>{x}</div>) }
}
render(){
return(<div className="row">{this.state.clocks}</div>
)};
}
export default ClockRow;
My Clock.js:
import React, { Component } from 'react';
import {Card, CardTitle, CardBody, CardFooter} from 'reactstrap';
class Clock extends Component {
constructor(props){
super(props);
this.state = {counter: 0, interval: parseInt(props.interval), title: props.title};
}
componentDidMount() {
this.timerID = setInterval(() => this.tick(), this.state.interval);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState((state) => ({
counter: state.counter + 1
}));
}
render() {
return (
<Card>
<CardTitle>{this.state.title}</CardTitle>
<CardBody>{this.state.counter}</CardBody>
<CardFooter>{this.state.interval}</CardFooter>
</Card>
);
}
}
export default Clock;
CodeSandbox:
https://codesandbox.io/s/zxlzzv05n3
ClockRow.js is surplus
Clock.js is not changed
App.js is changed, and "React styled":
import React, { Component } from "react";
import Clock from "./Clock";
class App extends Component {
constructor(props) {
super(props);
this.state = { items: [], inputTle: "Teszt", inputIval: 200 };
}
handleChangeTitle = event => {
this.setState({ inputTle: event.target.value });
};
handleChangeInterval = event => {
this.setState({ inputIval: event.target.value });
};
handleSubmit = event => {
console.log(this.state);
if (this.state.inputTle.length > 0 && this.state.inputIval > 9) {
this.setState(prevState => {
return {
items: [
...prevState.items,
{
title: this.state.inputTle,
interval: this.state.inputIval
}
]
};
});
}
event.preventDefault();
};
render() {
return (
<div>
<div className="row">
<h1 className="col text-center">Hello, React!</h1>
</div>
<div className="row">
<form onSubmit={this.handleSubmit}>
<label>
Title:{" "}
<input
type="text"
name="tle"
value={this.state.inputTle}
onChange={this.handleChangeTitle}
/>
</label>
<label>
Interval:{" "}
<input
type="number"
name="ival"
value={this.state.inputIval}
onChange={this.handleChangeInterval}
/>
</label>
<input type="submit" value="Add" />
</form>
</div>
<div className="row">
{this.state.items.map((item, index) => (
<div className="col" key={index}>
<Clock {...item} />
</div>
))}
</div>
</div>
);
}
}
export default App;

How to display data from Mob-x store on click

I have this component:
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import PropTypes from 'prop-types';
import './cardCheck.css';
#inject('auto')
#observer
class CardCheck extends Component {
render() {
const { auto } = this.props;
return (
<div>
<div className="newsletter-container">
<h1>Enter the ID of your card:</h1>
<div className="center">
<input type="number" />
<input type="submit" value="Check" onClick={event => {displayInfo}} />
</div>
<div className="results"></div>
</div>
<h1>Offers:</h1>
</div>
);
}
}
CardCheck.propTypes = {
auto: PropTypes.shape({
carCount: PropTypes.number
})
};
CardCheck.wrappedComponent.defaultProps = {
auto: autoPropTypeDefaults
};
export default CardCheck;
I want to make so that when someone clicks the input with value Check the div below with the className of results to be populated with my data from the store:
import { observable, action, computed } from 'mobx';
class Auto {
#observable
auto = [
{
name: 'Shop1'
},
{
name: 'Shop2'
}
];
#action
displayInfo() {
}
}
export { Auto };
I tried to make the displayInfo function iterate through the array with objects with a map from loadash but it didn't work, it did not displayed the data inside the div, how can I do this?
You can add an observable field on your CardCheck component that you toggle with the onClick event handler, and when the field is true you can display all entries in the auto array.
Example
class CardCheck extends Component {
#observable
checked = false;
onClick = event => {
event.preventDefault();
this.checked = !this.checked;
};
render() {
const { auto } = this.props;
return (
<div>
<div className="newsletter-container">
<h1>Enter the ID of your card:</h1>
<div className="center">
<input type="number" />
<input type="submit" value="Check" onClick={this.onClick} />
</div>
<div className="results">
{this.checked &&
auto.auto.map((a, index) => <div key={index}>{a.name}</div>)}
</div>
</div>
<h1>Offers:</h1>
</div>
);
}
}

My isLoading flag never set true in the constructor()

I'm working whith one representational component (ProjectFormUpdate) and his container (ProjectFormUpdateContainer). From the container, i send an document object Project and a flag isLoading. But in a Constructor() of ProjectFormUpdate, the flag is false... the state is never seted.
The representational componente
import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import { Projects } from '/imports/api/projects.js';
import PropTypes from 'prop-types'; // ES6
import { withTracker } from 'meteor/react-meteor-data';
export default class ProjectFormUpdate extends Component {
handleUpdate(event) {
event.preventDefault();
console.log("se modificó el estadoooo")
this.setState({
codigo: ReactDOM.findDOMNode(this.refs.codigoInput).value.trim(),
nombre: ReactDOM.findDOMNode(this.refs.nombreInput).value.trim()
});
}
handleSubmit(event){
this.setState({
codigo: ReactDOM.findDOMNode(this.refs.codigoInput).value.trim(),
nombre: ReactDOM.findDOMNode(this.refs.nombreInput).value.trim()
});
}
constructor(props) {
super(props);
if (!props.isLoading){
this.state = {
codigo: props.oneProject.codigo,
nombre: props.oneProject.nombre}
}
else{
this.state = {
codigo: 'dd',
nombre: 'ff'}
}
}
render() {
const { oneProject, isLoading } = this.props;
if (!isLoading){
this.setState = {
codigo: this.props.oneProject.codigo,
nombre: this.props.oneProject.nombre}
return (
<div className="col-xs-11">
<div className="box box-solid">
<form className="form" onSubmit={this.handleSubmit.bind(this)} >
<div className="box-body">
<div className="row">
<div className="col-xs-2">
<input
className = "form-control input-sm"
type="text"
ref="codigoInput"
placeholder="Código del Proyecto"
value = {this.state.codigo}//this.state.codigo}
onChange = {this.handleUpdate.bind(this)}
/>
</div>
<div className="col-xs-6">
<input
className = "form-control input-sm"
type="text"
ref="nombreInput"
placeholder="Título"
value = {this.state.nombre }
onChange = {this.handleUpdate.bind(this)}
/>
</div>
</div>
</div>
<div className="box-footer">
<button type="submit" className="btn btn-sm btn-primary btn-flat">Guardar</button>
</div>
</form>
</div>
</div>
);
}
else {return (<div></div>);}
}}
ProjectFormUpdate.propTypes = {
// This component gets the task to display through a React prop.
// We can use propTypes to indicate it is required
oneProject: React.PropTypes.object,
isLoading: React.PropTypes.bool,
};
The Container
import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Projects } from '/imports/api/projects.js';
import ProjectFormUpdate from './ProjectFormUpdate.jsx';
export default ProjectFormUpdateContainer = withTracker(({ key1 }) => {
const sub = Meteor.subscribe('projects');
var oneProject = Projects.findOne(key1);
var isLoading = !sub.ready();
return {
oneProject,
isLoading,
};
})(ProjectFormUpdate);
So... if i can't set the state, i can't set the form's values in a controled way. Any suggestion?
In order to set your components state outside of the constructor() function: you must call this.setState(). this.setState() will set it's first argument as the new state and subsequently call your component's render function.
Your if (!isLoading) statement is very dangerous. Assuming !isLoading == true: your render function will infinitely fire this.setState(), thereby locking your browser.
Your constructor function appears correct, as is. I would allow it to set the initial application state and handle the rest from within the render() function. Alternatively, you could set your initial state within the componentWillMount() or componentDidMount() functions found here.
Within your render() function, I would omit the if (!isLoading) part and instead try returning a loading component if (isLoading == true).
You can also apply the following logic directly to your <input/> elements to set your component's state with finesse:
<input value={this.state.key} onChange={(event) => this.setState({key: event.target.value})}/>
I've revised your ProjectFormUpdate component as follows:
import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import { Projects } from '/imports/api/projects.js';
import PropTypes from 'prop-types'; // ES6
import { withTracker } from 'meteor/react-meteor-data';
export default class ProjectFormUpdate extends Component {
handleSubmit(event){
event.preventDefault()
console.log()
}
constructor(props) {
super(props);
if (!props.isLoading) {
this.state = {
codigo: props.oneProject.codigo,
nombre: props.oneProject.nombre
}
}
else {
this.state = {
codigo: '',
nombre: ''
}
}
}
render() {
const { oneProject, isLoading } = this.props;
if (isLoading) {
return (
<div>isLoading == true</div>
)
}
return (
<div className="col-xs-11">
<div className="box box-solid">
<form className="form" onSubmit={this.handleSubmit.bind(this)} >
<div className="box-body">
<div className="row">
{/* Codigo. */}
<div className="col-xs-2">
<input className = "form-control input-sm" type="text" ref="codigoInput" placeholder="Código del Proyecto" value={this.state.codigo} onChange={(event) => this.setState({codigo: event.target.value})} />
</div>
{/* Nombre. */}
<div className="col-xs-6">
<input className = "form-control input-sm" type="text" ref="nombreInput" placeholder="Título" value={this.state.nombre} onChange={(event) => this.setState({nombre: event.target.value}))} />
</div>
</div>
</div>
<div className="box-footer">
<button type="submit" className="btn btn-sm btn-primary btn-flat">Guardar</button>
</div>
</form>
</div>
</div>
)
}
ProjectFormUpdate.propTypes = {
oneProject: React.PropTypes.object,
isLoading: React.PropTypes.bool,
};

How to hookup input boxes to Reactjs / Redux?

I not 100% sure if I am doing this right as per the redux design.
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import 'materialize-css/sass/materialize.scss';
import NavigationContainer from './NavigationContainer';
import AddStorageModal from './AddStorageModal.js'
import {loadAddStorageModal, createNewStorage} from '../actions/StorageActions.js'
import '../styles/main.scss';
class App extends React.Component {
render() {
return (
<div>
<NavigationContainer />
<AddStorageModal {...this.props} />
</div>
)
}
}
function mapStateToProps(state) {
return {
storages: state.storages
};
}
function matchDispatchToProps(dispatch){
return bindActionCreators({loadAddStorageModal: loadAddStorageModal, createNewStorage: createNewStorage}, dispatch);
}
export default connect(mapStateToProps, matchDispatchToProps)(App);
StorageActions
export function fetchStorage() {
return function(dispatch) {
var payload = [
{
id: 1,
name: "Fridge2"
},
{
id: 2,
name: "Closet2"
},
{
id: 3,
name: "Car2"
}
];
dispatch({type: "Fetch_Storage", payload: payload});
}
}
export function loadAddStorageModal(load) {
return function(dispatch) {
dispatch({type: "Load_Add_Storage_Modal", payload: load});
}
}
export function createNewStorage(storage) {
return function(dispatch) {
dispatch({type: "New_Storage_Created", payload: storage});
}
}
Reducer
export default function reducer(state = {
fetchedStorages: [],
openAddStorageModal: false
}, action) {
switch (action.type) {
case "Fetch_Storage": {
return {
fetchedStorages: action.payload
}
}
case "Load_Add_Storage_Modal": {
return {
openAddStorageModal: action.payload,
fetchedStorages: state.fetchedStorages
}
}
case "New_Storage_Created": {
return {
openAddStorageModal: false,
}
}
}
return state;
}
AddStorageModal
import React from 'react';
import 'materialize-css/sass/materialize.scss';
import 'materialize-css/js/materialize.js';
import 'font-awesome/scss/font-awesome.scss';
import '../styles/main.scss';
export default class AddStorageModal extends React.Component {
constructor() {
super();
this.state = {storageName: ""}
}
handleChange(event) {
this.setState({storageName: event.target.value});
}
render() {
if (this.props.storages.openAddStorageModal) {
$('#add-new-storage-modal').openModal({ dismissible: false });
}
return (
<div id="add-new-storage-modal" className="modal" >
<div className="modal-content">
<h6>Enter your new Storage (Freezer, Pantry, etc.) </h6>
<div className="row">
<form>
<div className="input-field col s12 m12 l12 ">
<input id="storage_name" type="text" className="validate" value={this.state.storageName} onChange={this.handleChange} />
<label htmlFor="storage_name">Storage Name</label>
</div>
<br />
<h4 className="center">OR</h4>
<h6>Enter in the sharing key you were given.</h6>
<div className="input-field col s12 m12 l12 ">
<input id="sharing_key" type="text" className="validate" />
<label htmlFor="sharing_key">Sharking Key</label>
</div>
</form>
</div>
</div>
<div className="modal-footer">
Add
<a href="#!" className="modal-action modal-close waves-effect waves-green btn-flat" onClick={() => this.props.loadAddStorageModal(false) }>Cancel</a>
</div>
</div>
)
}
}
I get
Uncaught TypeError: Cannot read property 'setState' of undefined
So I am not sure if this just means I am doing redux wrong or if I just made some general error.
You can't pass a generic function reference, you need to keep the reference to this. You have 2 options:
bind this to the function, like #nuway said in his answer.
Use an arrow function, which also keeps the this reference: onChange={ (event) => this.handleChange(event) }
you need to bind to this for the handleChange handler, otherwise this inside handleChange funtion won't be the react component but rather the input element itself.
onChange={this.handleChange.bind(this)}

Resources