React Hooks can only be called inside the body of a function component
up vote
2
down vote
favorite
How do I trigger useEffect()
on a button click, rather than on rendering the component?
When I use it inside a function like this, I get an error stating:
Hooks can only be called inside the body of a function component
function App() {
function buttonClicked() {
useEffect(() => {
// Fetch from API
});
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">App Title</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={buttonClicked}>Make API Call</button>
</div>
);
}
javascript reactjs react-hooks
add a comment |
up vote
2
down vote
favorite
How do I trigger useEffect()
on a button click, rather than on rendering the component?
When I use it inside a function like this, I get an error stating:
Hooks can only be called inside the body of a function component
function App() {
function buttonClicked() {
useEffect(() => {
// Fetch from API
});
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">App Title</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={buttonClicked}>Make API Call</button>
</div>
);
}
javascript reactjs react-hooks
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
How do I trigger useEffect()
on a button click, rather than on rendering the component?
When I use it inside a function like this, I get an error stating:
Hooks can only be called inside the body of a function component
function App() {
function buttonClicked() {
useEffect(() => {
// Fetch from API
});
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">App Title</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={buttonClicked}>Make API Call</button>
</div>
);
}
javascript reactjs react-hooks
How do I trigger useEffect()
on a button click, rather than on rendering the component?
When I use it inside a function like this, I get an error stating:
Hooks can only be called inside the body of a function component
function App() {
function buttonClicked() {
useEffect(() => {
// Fetch from API
});
}
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">App Title</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button onClick={buttonClicked}>Make API Call</button>
</div>
);
}
javascript reactjs react-hooks
javascript reactjs react-hooks
edited Nov 11 at 21:30
Yangshun Tay
8,42953565
8,42953565
asked Nov 11 at 13:37
Alan
3,61031624
3,61031624
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
Sounds like you misunderstood the usage of useEffect
. It's like componentDidUpdate
hook - it is being triggered depending on value change, not directly by some function. When render
method is called, useEffect
is also called. Hard to tell what is your goal, but from your snippet it makes most sense just to call fetch
without any hook. But to answer your question, one way to trigger useEffect
would be to update your state and you can create useEffect
hook to be triggered only if value of particular property is changed:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
Now when you click, useEffect
should be triggered, but because you added , [buttonClicked]
, it won't be called if any other property value changes.
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request frombuttonClicked
, it is considered as side-effect. If you for some reason still need to useuseEffect
hook, replacesetButtonClicked(true)
withsetButtonClicked(!buttonClicked)
- hook will be called every time button clicked
– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
add a comment |
up vote
3
down vote
The accepted answer isn't exactly correct IMO. If your goal is to trigger data fetching upon clicking on a button, there's no need for useEffect
. useEffect
is used to replace the lifecycle hooks - componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Think about this - without hooks, will you need these lifecycle hooks at all to achieve what you want? With classes, you simply have to use this.state
and a callback that triggers upon clicking of the button; you wouldn't use any of these lifecycle hooks.
The side effect you want to achieve is data fetching, but that's a user-triggered effect and useEffect
is not helpful here. useEffect
is only helpful when you want to have side effects during the lifecycle of the component.
The code below should do what you want to achieve with hooks, and you don't need useEffect
, you only need useState
.
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Sounds like you misunderstood the usage of useEffect
. It's like componentDidUpdate
hook - it is being triggered depending on value change, not directly by some function. When render
method is called, useEffect
is also called. Hard to tell what is your goal, but from your snippet it makes most sense just to call fetch
without any hook. But to answer your question, one way to trigger useEffect
would be to update your state and you can create useEffect
hook to be triggered only if value of particular property is changed:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
Now when you click, useEffect
should be triggered, but because you added , [buttonClicked]
, it won't be called if any other property value changes.
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request frombuttonClicked
, it is considered as side-effect. If you for some reason still need to useuseEffect
hook, replacesetButtonClicked(true)
withsetButtonClicked(!buttonClicked)
- hook will be called every time button clicked
– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
add a comment |
up vote
2
down vote
accepted
Sounds like you misunderstood the usage of useEffect
. It's like componentDidUpdate
hook - it is being triggered depending on value change, not directly by some function. When render
method is called, useEffect
is also called. Hard to tell what is your goal, but from your snippet it makes most sense just to call fetch
without any hook. But to answer your question, one way to trigger useEffect
would be to update your state and you can create useEffect
hook to be triggered only if value of particular property is changed:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
Now when you click, useEffect
should be triggered, but because you added , [buttonClicked]
, it won't be called if any other property value changes.
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request frombuttonClicked
, it is considered as side-effect. If you for some reason still need to useuseEffect
hook, replacesetButtonClicked(true)
withsetButtonClicked(!buttonClicked)
- hook will be called every time button clicked
– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Sounds like you misunderstood the usage of useEffect
. It's like componentDidUpdate
hook - it is being triggered depending on value change, not directly by some function. When render
method is called, useEffect
is also called. Hard to tell what is your goal, but from your snippet it makes most sense just to call fetch
without any hook. But to answer your question, one way to trigger useEffect
would be to update your state and you can create useEffect
hook to be triggered only if value of particular property is changed:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
Now when you click, useEffect
should be triggered, but because you added , [buttonClicked]
, it won't be called if any other property value changes.
Sounds like you misunderstood the usage of useEffect
. It's like componentDidUpdate
hook - it is being triggered depending on value change, not directly by some function. When render
method is called, useEffect
is also called. Hard to tell what is your goal, but from your snippet it makes most sense just to call fetch
without any hook. But to answer your question, one way to trigger useEffect
would be to update your state and you can create useEffect
hook to be triggered only if value of particular property is changed:
const [buttonClicked, setButtonClicked] = useState(false);
useEffect(() => {
// Fetch from API
}, [buttonClicked]);
<button onClick={() => setButtonClicked(true)}>Make API Call</button>
Now when you click, useEffect
should be triggered, but because you added , [buttonClicked]
, it won't be called if any other property value changes.
answered Nov 11 at 15:47
SkyHigh
42716
42716
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request frombuttonClicked
, it is considered as side-effect. If you for some reason still need to useuseEffect
hook, replacesetButtonClicked(true)
withsetButtonClicked(!buttonClicked)
- hook will be called every time button clicked
– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
add a comment |
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request frombuttonClicked
, it is considered as side-effect. If you for some reason still need to useuseEffect
hook, replacesetButtonClicked(true)
withsetButtonClicked(!buttonClicked)
- hook will be called every time button clicked
– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
From the docs: "The Effect Hook lets you perform side effects in function components". My goal is to perform a side effect on button click, not on render. Your solution with the state assumes I only want to perform a side effect on the first button click, what if I want perform it on every click? Also creating state variable simply to trigger useEffect seems clunky?
– Alan
Nov 11 at 17:48
So not uses this hook. If you invoke Http request from
buttonClicked
, it is considered as side-effect. If you for some reason still need to use useEffect
hook, replace setButtonClicked(true)
with setButtonClicked(!buttonClicked)
- hook will be called every time button clicked– SkyHigh
Nov 11 at 18:26
So not uses this hook. If you invoke Http request from
buttonClicked
, it is considered as side-effect. If you for some reason still need to use useEffect
hook, replace setButtonClicked(true)
with setButtonClicked(!buttonClicked)
- hook will be called every time button clicked– SkyHigh
Nov 11 at 18:26
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
Ah ok, I was assuming useEffect was to wrap all side effects for functional components. I'll just avoid using and avoid setting state so, thanks.
– Alan
Nov 11 at 18:47
add a comment |
up vote
3
down vote
The accepted answer isn't exactly correct IMO. If your goal is to trigger data fetching upon clicking on a button, there's no need for useEffect
. useEffect
is used to replace the lifecycle hooks - componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Think about this - without hooks, will you need these lifecycle hooks at all to achieve what you want? With classes, you simply have to use this.state
and a callback that triggers upon clicking of the button; you wouldn't use any of these lifecycle hooks.
The side effect you want to achieve is data fetching, but that's a user-triggered effect and useEffect
is not helpful here. useEffect
is only helpful when you want to have side effects during the lifecycle of the component.
The code below should do what you want to achieve with hooks, and you don't need useEffect
, you only need useState
.
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
add a comment |
up vote
3
down vote
The accepted answer isn't exactly correct IMO. If your goal is to trigger data fetching upon clicking on a button, there's no need for useEffect
. useEffect
is used to replace the lifecycle hooks - componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Think about this - without hooks, will you need these lifecycle hooks at all to achieve what you want? With classes, you simply have to use this.state
and a callback that triggers upon clicking of the button; you wouldn't use any of these lifecycle hooks.
The side effect you want to achieve is data fetching, but that's a user-triggered effect and useEffect
is not helpful here. useEffect
is only helpful when you want to have side effects during the lifecycle of the component.
The code below should do what you want to achieve with hooks, and you don't need useEffect
, you only need useState
.
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
add a comment |
up vote
3
down vote
up vote
3
down vote
The accepted answer isn't exactly correct IMO. If your goal is to trigger data fetching upon clicking on a button, there's no need for useEffect
. useEffect
is used to replace the lifecycle hooks - componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Think about this - without hooks, will you need these lifecycle hooks at all to achieve what you want? With classes, you simply have to use this.state
and a callback that triggers upon clicking of the button; you wouldn't use any of these lifecycle hooks.
The side effect you want to achieve is data fetching, but that's a user-triggered effect and useEffect
is not helpful here. useEffect
is only helpful when you want to have side effects during the lifecycle of the component.
The code below should do what you want to achieve with hooks, and you don't need useEffect
, you only need useState
.
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
The accepted answer isn't exactly correct IMO. If your goal is to trigger data fetching upon clicking on a button, there's no need for useEffect
. useEffect
is used to replace the lifecycle hooks - componentDidMount
, componentDidUpdate
, and componentWillUnmount
.
Think about this - without hooks, will you need these lifecycle hooks at all to achieve what you want? With classes, you simply have to use this.state
and a callback that triggers upon clicking of the button; you wouldn't use any of these lifecycle hooks.
The side effect you want to achieve is data fetching, but that's a user-triggered effect and useEffect
is not helpful here. useEffect
is only helpful when you want to have side effects during the lifecycle of the component.
The code below should do what you want to achieve with hooks, and you don't need useEffect
, you only need useState
.
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
function App() {
const [user, setUser] = React.useState(null);
function fetchData() {
fetch('https://randomuser.me/api/')
.then(results => results.json())
.then(data => {
setUser(data.results[0]);
});
};
return <div>
<p>{user ? user.name.first : 'No data'}</p>
<button onClick={fetchData}>Fetch Data</button>
</div>;
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
answered Nov 11 at 21:22
Yangshun Tay
8,42953565
8,42953565
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249297%2freact-hooks-can-only-be-called-inside-the-body-of-a-function-component%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown