简体   繁体   English

为什么每次渲染后都会执行useEffect?

[英]why is useEffect executing after each render?

Im having problems with my effect hook.我的效果挂钩有问题。 I only want it to render once.我只希望它渲染一次。 if I pass album.length or an empty array it returns an empty object.如果我传递album.length 或一个空数组,它会返回一个空的object。 If the album is added as a dependency then the effect renders as an infinite loop.如果将专辑作为依赖项添加,则效果将呈现为无限循环。 any help is appreciated.任何帮助表示赞赏。

const [album, setAlbum] = React.useState(initialState)
const {state} = React.useContext(AuthContext);


async function fetchData(){
 try{
  const res =await axios.get('http://localhost:5000/api/albums/all')
  const {data}= await res;
  setAlbum({...data,albums:res.data})
  console.log(album)
  }
  catch(err){
  console.log(err);
  }
}



 useEffect(() => {fetchData();}, []);


_______________________________________________________

componentDidMount(){
  axios.get('http://localhost:5000/api/albums/all')
.then(res=>{
    let albums=res.data.map((album)=>{
      return(
        <div key={album._id}>
       //display the album
          </div>
         </div>
        </div>
       )
       })
this.setState({albums:albums});

}) } }) }

const res =await axios.get('http://localhost:5000/api/albums/all')
const {data}= await res;
setAlbum({...data,albums:res.data})

Can you please explain this?你能解释一下吗? Why await res and why spread data and add it as albums as well?为什么要等待 res 以及为什么传播数据并将其添加为专辑?

You could write your own hook.你可以编写自己的钩子。 You should also declare the function fetchApi within the useEffect hook, that is why it re-renders the whole time.您还应该在 useEffect 挂钩中声明 function fetchApi ,这就是它一直重新渲染的原因。

Let's take your code and make a custom hook让我们使用您的代码并制作一个自定义钩子

import axios from 'axios';
import React, { useEffect, useState } from 'react';

function useAlbums() {
  const [albums, setAlbums] = useState([]);
  useEffect(() => {
    const fetchData = async () => {
      try {
        const { data } = await axios.get(
          'http://localhost:5000/api/albums/all',
        );
        setAlbums(data);
        console.log(albums);
      } catch (err) {
        console.log(err);
      }
    };
    fetchData();
  }, [albums]);

  return [albums, setAlbums];
}

const Component = () => {
  // use it in component
  const [albums] = useAlbums();

  return (
    <>
      {albums.map(({ _id }) => (
        <div key={_id}>{'add more content here'}</div>
      ))}
    </>
  );
};

Use with

const [albums, setAlbums] = useAlbums();

Hope this helps!希望这可以帮助!

Effects always run after the browser finishes to paint (except useLayoutEffect ).效果总是在浏览器完成绘制后运行(除了useLayoutEffect )。 Fetching data (which will be serialized into state ) inevitably will trigger an additional render获取数据(将被序列化为state )不可避免地会触发额外的render

const [data, setData] = useState(null)

useEffect(() =>{
    fetchAPI().then(res => setData(res))
},[])//Will run after the first render and trigger another one

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我收到此错误:React Hook useEffect 内部的变量在每次渲染后都会丢失? - Why i am getting this error: variable from inside React Hook useEffect will be lost after each render? 来自 React Hook 内部的变量 useEffect 将在每次渲染后丢失 - Variable from inside React Hook useEffect will be lost after each render 为什么 useEffect 在第一次渲染时运行? - why is useEffect running on first render? 如何修复:每次渲染后,React Hook useEffect 中对“主题”变量的赋值将丢失 - How to fix: Assignments to the 'theme' variable from inside React Hook useEffect will be lost after each render 每次渲染后,从 React Hook useEffect 内部对 'timeInterval' 变量的分配将丢失 - Assignments to the 'timeInterval' variable from inside React Hook useEffect will be lost after each render useEffect 在初始渲染后不触发 - useEffect does not trigger after initial render 每次渲染后会调用哪个 useEffect? - Which useEffect will be called after every Render? 在 useEffect 之后在 React 路由器 dom 中渲染路由 - Render route in React router dom after useEffect React native:渲染后使用效果显示 - React native : useEffect display after render 为什么我的 useEffect 没有在第一次渲染时运行? - Why is my useEffect not running on first render?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM