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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With