1

I have a react component that will throws an error when I try to dispatch a redux action. Here is the component:

import React from 'react'; 
import { connect } from 'react-redux';
import { createBook } from './actions/books';  
import './InputForm.css'; 

export class InputForm extends React.Component {

    onFormSubmit(event) {
        event.preventDefault(); 
        let newBook = {
            title: this.titleInput.value, 
            author: this.authorInput.value, 
            description: this.descriptionInput.value
        }
        this.props.dispatch(createBook(newBook)); 
    }

    render() {
        return (
            <div>
                <form onSubmit={event => this.onFormSubmit(event)}> 
                    <input className="form-input" placeholder="Title" ref={input => this.titleInput = input} />
                    <input className="form-input" placeholder="Author" ref={input => this.authorInput = input} />
                    <input className="form-input form-text-area" placeholder="Description" ref={input => this.descriptionInput = input} />
                    <button className="form-button" type="submit">Submit</button>
                </form>
            </div>
        )
    }
}

export default connect()(InputForm); 

This is the line that creates the problem:

this.props.dispatch(createBook(newBook)); 

I'm not sure what's going on. Here is the error I get:

Uncaught TypeError: this.props.dispatch is not a function
    at InputForm.onFormSubmit (InputForm.js:15)
    at onSubmit (InputForm.js:21)
    at HTMLUnknownElement.callCallback 

I have another component set up almost identically using a different action. It works fine. Here is that component if anyone wants to compare:

import React from 'react'; 
import './Book.css'; 
import { deleteBook } from './actions/books'; 
import { connect } from 'react-redux'; 

export class Book extends React.Component {

    onDelete(event) {
        this.props.dispatch(deleteBook(this.props.id)); 
    }

    render() {
        return (
            <div className="book-container">
                <h4>{this.props.title}</h4>
                <p>{this.props.author}</p>
                <p>{this.props.description}</p>
                <p>{this.props.id}</p>
                <button className="book-delete-button" onClick={event => this.onDelete(event)}>Delete</button>
            </div>
        )
    }
}

export default connect()(Book); 

Dunno what's going on here. Please help!

5
  • 1
    Have you tried to console.log your this.props to see what it's pointing at? Commented Feb 1, 2018 at 18:21
  • It has no props when I try to console.log them. But why? Commented Feb 1, 2018 at 18:24
  • Just curious, I was dealing with something similar the other day. These components are both wrapped in a page with connect as well? Commented Feb 1, 2018 at 18:27
  • can you show the code where you import and use InputForm? the issue might be the way you import the component. you export it in 2 ways, a named export (which may cause this issue if you import it) and a default export (which this is the way you should import it) Commented Feb 1, 2018 at 19:37
  • Really hard for us to debug this, you'd be better off inspecting your react element tree using the react dev tools extension. Seeing the component hierarchy and what the props are for all your components will tell you more than any of us can. Commented Feb 1, 2018 at 19:49

2 Answers 2

3

Seems like there at least 2 issues here that can cause a problem.

  1. It depends on how you import the components. You are exporting 2 components in each module:

    • A named export (the component)
    • And a default export (the new connected component).

    If you import the named export:

    import { InputForm } from './path'; 
    

    You will not have the redux related props as this is not the connected component.
    This is why one of your other connected components is working fine even though it seems to have the same code and structure pattern.
    You probably import it the way you should (default import).

    Make sure you import the default component:

    import InputForm from './path';
    
  2. Another thing that caught my eye, is that you are not binding the event handler onFormSubmit, so i expect the this to be the element that triggered the event. Though i think if that was the issue, you would get a different error anyway.
Sign up to request clarification or add additional context in comments.

3 Comments

+1 This is a good catch, to clarify, unconnected-InputForm is being exported as a property (inport { InputForm }) and connected-InputForm is being exported as the default. Using the unconnected component could definitely cause this problem.
I usually don't export both under the same name for this very reason. (if i need the unconnected version for tests, i'll export it under a different name)
@caesay indeed, i share the same pattern.
0

I had imported the disconnected version in the container component. Stupid mistake.

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.