为什么我的 useEffect 在页面加载时反应函数 运行 尽管我给它第二个值数组
Why does my useEffect react function run when the page loads although I am giving it a second value array
为什么我的 useEffect 反应函数 运行 在每个页面加载时都在使用 运行 宁,尽管给它一个带有 query
变量的第二个值数组?
useEffect( () => {
getRecipes();
}, [query]);
当 query
状态变量改变时,它不应该只 运行 吗?除了 useEffect 函数之外,我没有使用 getRecipes
函数。
import React, {useEffect, useState} from 'react';
import './App.css';
import Recipes from './components/Recipes/Recipes';
const App = () => {
// Constants
const APP_ID = '111';
const APP_KEY = '111';
const [recipes, setRecipes] = useState([]);
const [search, setSearch] = useState('');
const [query, setQuery] = useState('');
const [showRecipesList, setShowRecipesList] = useState(false);
// Lets
let recipesList = null;
// Functions
useEffect( () => {
getRecipes();
}, [query]);
// Get the recipie list by variables
const getRecipes = async () => {
const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}&from=0&to=3&calories=591-722&health=alcohol-free`);
const data = await response.json();
console.log(data.hits);
setRecipes(data.hits);
}
// Update the search constant
const updateSearch = e => {
console.log(e.target.value);
setSearch(e.target.value);
}
const runQuery = e => {
e.preventDefault();
setQuery(search);
}
// List recipes if ready
if (recipes.length) {
console.log(recipes.length);
recipesList = <Recipes recipesList={recipes} />
}
return (
<div className="App">
<form className='search-app' onSubmit={ runQuery }>
<input
type='text'
className='search-bar'
onChange={ updateSearch }
value={search}/>
<button
type='submit'
className='search-btn' > Search </button>
</form>
<div className='recipesList'>
{recipesList}
</div>
</div>
);
}
export default App;
UseEffect hook 相当于 componentDidMount、componentDidUpdate 和 componentWillUnmount 组合的 React class 组件 lifecycles.but DOM.componentDidMount 和 useEffect 运行 的作用时间不同安装后。但是,与之前相比,在绘画提交到屏幕之后使用 Effect 运行s。这意味着如果你需要从 DOM 读取,你会得到一个闪烁,然后同步设置状态以使新的 UI.useLayoutEffect 被设计为与 componentDidMount 具有相同的时序。所以 useLayoutEffect(fn, []) 比 useEffect(fn, []) 更接近于 componentDidMount() —— 至少从计时的角度来看是这样。
这是否意味着我们应该改用 useLayoutEffect?
可能不会。
如果您确实想通过同步设置状态来避免闪烁,请使用 useLayoutEffect。但由于这些情况很少见,所以大多数时候您会希望使用 useEffect。
一个useEffect
相当于componentDidMount
,所以在组件挂载的时候会运行一次,只有其中一个依赖的时候才会重新运行在依赖项数组中定义更改。
如果你只想在 query
依赖项有值时调用 getRecipes()
,你可以像这样在条件中调用它:
useEffect(() => {
if(query) {
getRecipes()
}
}, [query])
此外,由于您的 useEffect
正在调用一个函数 (getRecipes
),该函数被声明为 在 之外 使用效果,但 在[内部] 组件,您应该将函数声明移动到 useEffect
内部并添加适当的依赖项,或者将您的函数包装在 useCallback
中并将函数添加为 useEffect
.
请参阅 React docs 了解为什么这很重要。
为什么我的 useEffect 反应函数 运行 在每个页面加载时都在使用 运行 宁,尽管给它一个带有 query
变量的第二个值数组?
useEffect( () => {
getRecipes();
}, [query]);
当 query
状态变量改变时,它不应该只 运行 吗?除了 useEffect 函数之外,我没有使用 getRecipes
函数。
import React, {useEffect, useState} from 'react';
import './App.css';
import Recipes from './components/Recipes/Recipes';
const App = () => {
// Constants
const APP_ID = '111';
const APP_KEY = '111';
const [recipes, setRecipes] = useState([]);
const [search, setSearch] = useState('');
const [query, setQuery] = useState('');
const [showRecipesList, setShowRecipesList] = useState(false);
// Lets
let recipesList = null;
// Functions
useEffect( () => {
getRecipes();
}, [query]);
// Get the recipie list by variables
const getRecipes = async () => {
const response = await fetch(`https://api.edamam.com/search?q=${query}&app_id=${APP_ID}&app_key=${APP_KEY}&from=0&to=3&calories=591-722&health=alcohol-free`);
const data = await response.json();
console.log(data.hits);
setRecipes(data.hits);
}
// Update the search constant
const updateSearch = e => {
console.log(e.target.value);
setSearch(e.target.value);
}
const runQuery = e => {
e.preventDefault();
setQuery(search);
}
// List recipes if ready
if (recipes.length) {
console.log(recipes.length);
recipesList = <Recipes recipesList={recipes} />
}
return (
<div className="App">
<form className='search-app' onSubmit={ runQuery }>
<input
type='text'
className='search-bar'
onChange={ updateSearch }
value={search}/>
<button
type='submit'
className='search-btn' > Search </button>
</form>
<div className='recipesList'>
{recipesList}
</div>
</div>
);
}
export default App;
UseEffect hook 相当于 componentDidMount、componentDidUpdate 和 componentWillUnmount 组合的 React class 组件 lifecycles.but DOM.componentDidMount 和 useEffect 运行 的作用时间不同安装后。但是,与之前相比,在绘画提交到屏幕之后使用 Effect 运行s。这意味着如果你需要从 DOM 读取,你会得到一个闪烁,然后同步设置状态以使新的 UI.useLayoutEffect 被设计为与 componentDidMount 具有相同的时序。所以 useLayoutEffect(fn, []) 比 useEffect(fn, []) 更接近于 componentDidMount() —— 至少从计时的角度来看是这样。 这是否意味着我们应该改用 useLayoutEffect? 可能不会。 如果您确实想通过同步设置状态来避免闪烁,请使用 useLayoutEffect。但由于这些情况很少见,所以大多数时候您会希望使用 useEffect。
一个useEffect
相当于componentDidMount
,所以在组件挂载的时候会运行一次,只有其中一个依赖的时候才会重新运行在依赖项数组中定义更改。
如果你只想在 query
依赖项有值时调用 getRecipes()
,你可以像这样在条件中调用它:
useEffect(() => {
if(query) {
getRecipes()
}
}, [query])
此外,由于您的 useEffect
正在调用一个函数 (getRecipes
),该函数被声明为 在 之外 使用效果,但 在[内部] 组件,您应该将函数声明移动到 useEffect
内部并添加适当的依赖项,或者将您的函数包装在 useCallback
中并将函数添加为 useEffect
.
请参阅 React docs 了解为什么这很重要。