8

I have been working on this for long but didn't find a solution:

I get Cannot read property 'dispatch' of undefined whenever the handleInputChange function is called.

This is the basic layout of my app:

App.tsx

import * as React from 'react';
import { BrowserRouter as Router, Route, Switch} from 'react-router-dom';

import SuperSignupScreen from './screens/SuperSignupScreen'

import './App.css';
import {connect, Dispatch} from "react-redux";


export type SessionProps = {
}

class AppImpl extends React.PureComponent<SessionProps & { dispatch: Dispatch<{}> }, {}> {
  render() {
      return(
          <Router>
            <Switch>
                <Route path="/superSignup" component={SuperSignupScreen}/>
                 <Route key="404" component={NotFoundScreen} />
            </Switch>
          </Router>
      )
  }
}

function mapStateToProps(state: { session: SessionProps }): SessionProps {
    return state.session;
}


const App = connect(mapStateToProps)(AppImpl);

export default App;

and this is SuperSignupScreen:

    import * as React from "react";
import {TextField, RaisedButton} from 'material-ui';
import {connect, Dispatch} from "react-redux";
import {SuperSignup, updateForm} from "../actions/SuperSignupActions";

export type SignupScreenProps = {signup: SuperSignup};

class SuperSignupScreenImpl extends React.PureComponent<HomeScreenProps & {dispatch: Dispatch<{}>}, {}> {
    render() {

        return(

                <TextField
                hintText = "Name"
                onChange = {this.handleInputChange}
                name = "name"
            >


                </TextField>
                    <RaisedButton label="Submit" primary={true}/>

        );
    }
    handleInputChange(event){
        const target = event.target;
        const value = target.value;
        this.props.dispatch(updateForm(value));
    }
}

function mapStateToProps(state: {signup: SuperSignup}): SignupScreenProps {
    return {signup: state.signup};
}

const SuperSignupScreen = connect(mapStateToProps)(SuperSignupScreenImpl);

export default SuperSignupScreen;

and this is index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import {applyMiddleware, combineReducers, createStore} from 'redux';
import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

import './index.css';
import App from './App';
import thunk from "redux-thunk";

const rootReducer = combineReducers({

});

const store = createStore(rootReducer, applyMiddleware(thunk));

ReactDOM.render((
    <Provider store={store}>
        <MuiThemeProvider muiTheme={getMuiTheme(darkBaseTheme)}>
            <App/>
        </MuiThemeProvider>
    </Provider>

), document.getElementById('root'));

I've spent a good time trying to understand the issue, would be grateful if you can help.

2 Answers 2

4

Try binding this when passing handleInputChange to onChange of the TextField:

 <TextField
   hintText = "Name"
   onChange = {this.handleInputChange.bind(this)}
   name = "name"
 >

This is a good article explaining why and when to bind this in react components.

Sign up to request clarification or add additional context in comments.

Comments

2

I'm not sure if it's a correct way of dispatching an action. Usually i do something like this:

...
import { connect } from 'react-redux';
import { sayHello } from './my/actions/';
...
class Example extends Component{
  constructor(props){
    super(props);
    ...
    this.handleOnClick = this.handleOnClick.bind(this);
    ...
  }
  ...
  handleOnClick(){
    this.props.sayHello()
  }
  ...
}

const mapStateToProps = (state) => state
const mapDispatchToProps = { sayHello, doIt, ...}

export default connect(mapStateToProps, mapDispatchToProps)(Example).

Here you can read more about mapDispatchToProps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.