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 definingsetLoading
? – 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 theCustomForm
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
2 Answers
Reset to default 6For 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.
- A better way would be, directly define it inside your ponent.
- and, we cant call the callback function like this
doAction("finish", setLoading)
if it is taking any parameter. since,setLoading
is expecting a valuetrue
orfalse
.
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),
}
}