最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Uncaught TypeError: setLoading is not a function - Stack Overflow

programmeradmin1浏览0评论

I am trying to pass a React hook to react-redux. I pass in loading and setLoading hook. However, when I try to use setLoading I get an error:

Uncaught TypeError: setLoading is not a function

I'm really not sure what I am misunderstanding but I am new to React and even newer to react-redux. I am using mapStateToProps but can't figure out how to use Hooks with it.

import React from "react"
import { connect } from "react-redux"
import Button from '@material-ui/core/Button';

export const CustomForm = ({ loading, setLoading, doAction }) => {
  const onClick = (e) => {
    e.preventDefault();
    setLoading(true);
    doAction("finish", setLoading)
  };

  return (
    <React.Fragment>
        <form onSubmit={onClick}>
            <Button type="submit">
              Submit
            </Button>
        </form>
    </React.Fragment>
  )
}

const mapStateToProps = state => {
  return {
    loading: state.loading,
    setLoading: state.setLoading
  }
}

const mapDispatchToProps = dispatch => {
  return {
    doAction: (action, setLoading) => dispatch(action, setLoading),
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CustomForm)

Here is how I call CustomForm:

const [loading, setLoading] = React.useState(false);
<CustomForm loading={loading} setLoading={setLoading} />

EDIT: I need loading and setLoading defined outside the ponent because I use them outside of the ponent also.

I am trying to pass a React hook to react-redux. I pass in loading and setLoading hook. However, when I try to use setLoading I get an error:

Uncaught TypeError: setLoading is not a function

I'm really not sure what I am misunderstanding but I am new to React and even newer to react-redux. I am using mapStateToProps but can't figure out how to use Hooks with it.

import React from "react"
import { connect } from "react-redux"
import Button from '@material-ui/core/Button';

export const CustomForm = ({ loading, setLoading, doAction }) => {
  const onClick = (e) => {
    e.preventDefault();
    setLoading(true);
    doAction("finish", setLoading)
  };

  return (
    <React.Fragment>
        <form onSubmit={onClick}>
            <Button type="submit">
              Submit
            </Button>
        </form>
    </React.Fragment>
  )
}

const mapStateToProps = state => {
  return {
    loading: state.loading,
    setLoading: state.setLoading
  }
}

const mapDispatchToProps = dispatch => {
  return {
    doAction: (action, setLoading) => dispatch(action, setLoading),
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CustomForm)

Here is how I call CustomForm:

const [loading, setLoading] = React.useState(false);
<CustomForm loading={loading} setLoading={setLoading} />

EDIT: I need loading and setLoading defined outside the ponent because I use them outside of the ponent also.

Share Improve this question edited Dec 16, 2020 at 3:09 user75892734905 asked Dec 15, 2020 at 5:01 user75892734905user75892734905 791 silver badge7 bronze badges 6
  • 1 Where and how do you define setLoading? – BlackMath Commented Dec 15, 2020 at 5:09
  • 1 So the error isn't a React or Redux one, it's just a Javascript one. In the parent of CustomForm how are you defining setLoading? – Jayce444 Commented Dec 15, 2020 at 5:10
  • I am defining setLoading as a Hook from the container that holds the form: const [loading, setLoading] = React.useState(false); – user75892734905 Commented Dec 15, 2020 at 5:13
  • In your CustomForm ponent declare a function as such: update(nextState) { setLoading(nextState);} pass in this method instead into the CustomForm ponent, like this: <CustomForm loading={loading} setLoading={update} />. – newbieprogrammer Commented Dec 15, 2020 at 5:23
  • @newbieprogrammer I get the same error with that – user75892734905 Commented Dec 16, 2020 at 0:36
 |  Show 1 more ment

2 Answers 2

Reset to default 6

For me it was a pretty silly mistake. Incase someone faces it, it may help.

So I was doing this

const {loading, setLoading} = useState(false);

instead of this:

const [loading, setLoading] = useState(false);

Keep an eye on the curly brackets and square brackets. I mistakenly typed the curly braces

I had same doubt as @BlackMath, later I found you have defined it in last.

  1. A better way would be, directly define it inside your ponent.
  2. and, we cant call the callback function like this doAction("finish", setLoading) if it is taking any parameter. since, setLoading is expecting a value true or false.
import React from "react"
import { connect } from "react-redux"
import Button from '@material-ui/core/Button';

export const CustomForm = ({ doAction }) => {

  const [loading, setLoading] = React.useState(false);

  const onClick = (e) => {
    e.preventDefault();
    setLoading(true);
    doAction("finish", ()=>{ 
      setLoading(false); //or true based on your logic
    })
  };

  return (
    <React.Fragment>
        <form onSubmit={onClick}>
            <Button type="submit">
              Submit
            </Button>
        </form>
    </React.Fragment>
  )
}

const mapStateToProps = state => {
  return {
    loading: state.loading,
    setLoading: state.setLoading
  }
}

const mapDispatchToProps = dispatch => {
  return {
    doAction: (action, setLoading) => dispatch(action, setLoading),
  }
}
发布评论

评论列表(0)

  1. 暂无评论