admin管理员组文章数量:1203940
So I have the following situation when using a useEffect
that calls a functions that depends on state.
Example:
// INSIDE APP COMPONENT
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
function someFunction() {
return someState + 1;
}
React.useEffect(() => {
const newState = someFunction(); // 'someFunction' IS BEING CALLED HERE
setSomeState(newState);
},[someTrigger])
QUESTIONS:
In this case, should I declare someFunction
inside the useEffect()
or is it safe to keep it outside (but inside component's body)?
I could add it to the dependency
array, but it will hurt the redability of my code, since I want to focus on the trigger
.
Since the useEffect()
will run after a fresh render, is it safe to assume that it will have fresh copies of the functions that I'm calling inside of it?
Is there a basic rule of when you should declare functions inside the useEffect
hook or when is it mandatory that you add it to the dependency array?
EDIT: Note that it's necessary that the useEffect
has fresh copies of those functions, since those functions need to access some fresh up-to-date state
variable.
NOTE:
This code triggers the following eslint warning on CodeSandbox. Although it works just fine.
React Hook React.useEffect has a missing dependency: 'someFunction'. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)eslint
REAL CASE SCENARIO:
This is a simplified example. In my real case, this is a product search page with filters components. So when I click on a filter to activate it (let's say, price <= 50
), I'm triggering a useEffect()
that is "listening" for the activePriceFilters
state variable. That effect then calls a function (someFunction
in the example) that will calculate the filteredList
and will set the new productList
state with the new filteredList
.
SNIPPET
function App() {
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
function someFunction() {
return someState + 1;
}
React.useEffect(() => {
const newState = someFunction();
setSomeState(newState);
},[someTrigger])
return(
<React.Fragment>
<div>I am App</div>
<div>My state: {someState}</div>
<button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src=".8.3/umd/react.production.min.js"></script>
<script src=".8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
So I have the following situation when using a useEffect
that calls a functions that depends on state.
Example:
// INSIDE APP COMPONENT
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
function someFunction() {
return someState + 1;
}
React.useEffect(() => {
const newState = someFunction(); // 'someFunction' IS BEING CALLED HERE
setSomeState(newState);
},[someTrigger])
QUESTIONS:
In this case, should I declare someFunction
inside the useEffect()
or is it safe to keep it outside (but inside component's body)?
I could add it to the dependency
array, but it will hurt the redability of my code, since I want to focus on the trigger
.
Since the useEffect()
will run after a fresh render, is it safe to assume that it will have fresh copies of the functions that I'm calling inside of it?
Is there a basic rule of when you should declare functions inside the useEffect
hook or when is it mandatory that you add it to the dependency array?
EDIT: Note that it's necessary that the useEffect
has fresh copies of those functions, since those functions need to access some fresh up-to-date state
variable.
NOTE:
This code triggers the following eslint warning on CodeSandbox. Although it works just fine.
React Hook React.useEffect has a missing dependency: 'someFunction'. Either include it or remove the dependency array. (react-hooks/exhaustive-deps)eslint
REAL CASE SCENARIO:
This is a simplified example. In my real case, this is a product search page with filters components. So when I click on a filter to activate it (let's say, price <= 50
), I'm triggering a useEffect()
that is "listening" for the activePriceFilters
state variable. That effect then calls a function (someFunction
in the example) that will calculate the filteredList
and will set the new productList
state with the new filteredList
.
SNIPPET
function App() {
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
function someFunction() {
return someState + 1;
}
React.useEffect(() => {
const newState = someFunction();
setSomeState(newState);
},[someTrigger])
return(
<React.Fragment>
<div>I am App</div>
<div>My state: {someState}</div>
<button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Share
Improve this question
edited Jul 2, 2019 at 11:42
cbdeveloper
asked Jul 2, 2019 at 10:16
cbdevelopercbdeveloper
31.3k44 gold badges196 silver badges392 bronze badges
1
|
3 Answers
Reset to default 12A decision to define a function within or outside of useEffect depends on where all the functions is called.
If your function is called only from within the useEffect then it makes sense to define it within the useEffect.
However is the same function is being called from within useEffect as well as other event handlers or other effects, you need to define it outside of useEffect
PS. in your case you are just updating the state for which you needn't define a separate function
function App() {
const [someState, setSomeState] = React.useState(0);
const [someTrigger, setSomeTrigger] = React.useState(false);
React.useEffect(() => {
setSomeState(oldState => oldState + 1);
},[someTrigger])
return(
<React.Fragment>
<div>I am App</div>
<div>My state: {someState}</div>
<button onClick={()=>setSomeTrigger((prevState) => !prevState)}>Click</button>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
As far as you scenario is concerned, you would write it like
useEffect(() => {
const calcVal = (oldState) => {
// calculate previous state based on oldState
}
setSomeState(calcVal);
}, [activePriceFilters])
Setting another state should not be an effect at all.
const [someState, setSomeState] = React.useState(0);
function incrementState() {
setSomeState(someState => someState + 1);
}
From performance point of view.
Declaring functions inside the useEffect hook will cause them to be recreated every time the useEffect is triggered.
When you declare a function inside the useEffect hook, it gets redefined each time the component is rendered, as the useEffect hook runs after every render where its dependency array changes. This behavior can lead to unnecessary overhead, particularly if the function doesn't rely on any external variables within the useEffect.
本文标签: javascriptWhere should I declare functions that are called inside a useEffect() hookStack Overflow
版权声明:本文标题:javascript - Where should I declare functions that are called inside a useEffect() hook? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738672948a2106098.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
useEffect
– devserkan Commented Jul 2, 2019 at 10:33