3

I'm trying to learn to React - Redux. I created an Exam Component like the following:

class ExamHome extends React.Component {

    constructor(props) {
        super(props)
    }

    render() {
        return (
            <TabPane>
                <Exam />
            </TabPane>
        )
    }
}

export default ExamHome;

I created a Exam React component like the following:

class Exam extends React.Component {

    constructor(props) {
        super(props)
    }

    render() {
        return (
            "hello"
        )
    }
}

const mapStateToProps = state => {
    return {
        examUrl: state.examApp.examUrl
    }
};

export default connect(mapStateToProps, {
    showExam
})(Exam);

Here's my reducer:

let initialState = {
    examUrl: null
}

const exam = (state = initialState, action) => {
    switch (action.type) {
        case "SHOW_EXAM":
            return { ...state, examUrl: action.examToken }

        default:
            return state
    }
};

export default exam

And here's my action:

export const showExam = t => {
    return dispatch => dispatch({
        type : "SHOW_EXAM", examToken : t
    })
}

It works fine if i remove connect If I add connect i get the following error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check the render method of ExamHome.

I tried all the possible solutions I found in Stackoverflow but none of them working. Thanks for your help.

Edit:

Here's rootReducer.js

import { combineReducers } from "redux"
import { connectRouter } from 'connected-react-router'
import customizer from "./customizer/"
import auth from "./auth/"
import navbar from "./navbar/Index"
import exam from "./exam/exam"

const rootReducer = (history) => combineReducers({
  customizer: customizer,
  auth: auth,
  navbar: navbar,
  exam: exam,
  router: connectRouter(history)
})

export default rootReducer
savepopulation
  • 11,736
  • 4
  • 55
  • 80
  • Can you show the combineReducers? Also, declare propTypes for Exam (Exam.propTypes ...) – Ergis Nov 16 '20 at 19:36
  • i added reducer code but i don't know what you mean by declare propTypes. can you show an example? i did not see anything like that in the examples that i follow. – savepopulation Nov 16 '20 at 19:40
  • i fixed but still same error. – savepopulation Nov 16 '20 at 19:46
  • revert everything back as it was, and include the imports that you do in `Exam` and `ExamHome`. Probably u might have an import which is with curly braces when it shouldn't or vice verca. – Ergis Nov 16 '20 at 19:54
  • something [similar](https://stackoverflow.com/questions/34130539/uncaught-error-invariant-violation-element-type-is-invalid-expected-a-string#:~:text=createElement%3A%20type%20is%20invalid%20%2D%2D,the%20file%20it's%20defined%20in.&text=but%20got%3A%20undefined.-,You%20likely%20forgot%20to%20export%20your,the%20file%20it's%20defined%20in.). Hope it helps – Ergis Nov 16 '20 at 20:03
  • thanks. i checked all these but non of them worked. – savepopulation Nov 16 '20 at 20:04
  • If you're new to react and the project is not old, why don't you use React `hooks`? The new versions of React don't need `HOC`s like `connect`. Have you read about them? Everything became absolutely easier with hooks. – erfoon Nov 16 '20 at 20:12
  • 1
    Does this answer your question? [Redux \`connect()\` return an object](https://stackoverflow.com/questions/56416629/redux-connect-return-an-object) – diedu Nov 16 '20 at 20:22
  • i'm using react dom 16.12.0 so i think it's not a solution for me. – savepopulation Nov 16 '20 at 20:38
  • What is `TabPane`? is it from a 3rd party library? have you tried rendering `Exam` without it? – diedu Nov 17 '20 at 01:51
  • I created a codesandbox assuming you're using redux-thunk and antd https://codesandbox.io/s/great-northcutt-v8mtw?file=/src/App.js, and it works, so I think you'll need to research more your own code, maybe a 3rd party lib is using a old version of react, try checking `npm list | grep react` – diedu Nov 17 '20 at 02:23

1 Answers1

0

You just need to define your dispatch and return to connect function and run it using componentDidMount:

import * as Actions from "path of showExam, Actions file only";

class Exam extends React.Component {

componentDidMount() {
    props.onShowExam("any value you want in default");
  }

    constructor(props) {
        super(props)
    ....
}

const mapStateToProps = state => {
    return {
        examUrl: state.examApp.examUrl
    }
};

const mapDispatchToProps = dispatch => {
    return {
         onShowExam: (val) => dispatch(Actions.showExam(val))
    }
};

export default connect(mapStateToProps, mapDispatchToProps)(Exam);
Farhan Asif
  • 148
  • 1
  • 6