【问题标题】:How can I avoid the infinite loop in useEffect?如何避免 useEffect 中的无限循环?
【发布时间】:2020-06-25 14:16:35
【问题描述】:

我需要你的帮助。我正在使用 useContext 和 useReducer 钩子创建一个应用程序,但我遇到了问题。我有一个功能可以从我的数据库中获取所有笔记。我在 useEffect 挂钩中调用了该函数:

import React, { useContext, useEffect } from "react";
import { useTranslation } from "react-i18next";
//Context
import AuthContext from "../../context/auth/authContext";
import NoteContext from '../../context/notes/noteContext';
//Components
import { Row, Col, Container, Button } from "react-bootstrap";
import Canva from '../Canva/Canva';
import Note from '../Note/Note';

const Dashboard = () => {
  const { t, i18n } = useTranslation();
  const authContext = useContext(AuthContext);
  const { authUser, user } = authContext;
  const noteContext = useContext(NoteContext);
  const { notes, getNotes, addNote } = noteContext;
  useEffect(() => {
    getNotes();
  }, []);
  return (
    <>
      <Container>
        <Row>
          <Col sm={12} md={10}>
            <Button onClick={() => addNote()} type='button' className='mb-2'>
              Añadir elemento
            </Button>
            <Canva>
              {notes && (notes.map(note => {
                return (
                  <Note key={note._id} note={note} />
                )
              }))}
            </Canva>
          </Col>
        </Row>
      </Container>
    </>
  );
};

export default Dashboard;

如果我以这种方式调用该函数,我的状态不会改变:

notes: undefined

但是,如果我在 useEffect 中引入依赖项,我的应用程序就会陷入无限循环。例如:

useEffect(() => {
  getNotes();
}, [notes])

//Or:
useEffect(() => {
  getNotes()
}, [getNotes])

如何避免死循环?

【问题讨论】:

  • 显示 NoteContext 里面的内容
  • @IanVasco 准备就绪

标签: reactjs


【解决方案1】:

您需要使用 2 个 useEffect 挂钩,一个用于获取数据,第二个用于继续它:

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

useEffect(() => {
  if (notes && notes.length) {
    ....setState or what else
  }
}, [notes]);

【讨论】:

  • 感谢您的帮助,但它不起作用,因为 getNotes 修改了笔记状态
【解决方案2】:

我的笔记状态如下:

import React, { useReducer } from 'react';
import clientAxios from '../../config/clientAxios';
import NoteContext from './noteContext';
import NoteReducer  from './noteReducer';
import {
  GET_NOTES,
  ADD_NOTE,
  DELETE_NOTE,
  UPDATE_NOTE,
} from '../../types';
const NoteState = ({ children }) => {
  const initialState = {
    notes: [],
    noteError: false,
  };

  const [state, dispatch] = useReducer(NoteReducer, initialState);

  const getNotes = async () => {
    try {
      const response = await clientAxios.get('/user/Notes');
      dispatch({
        type: GET_NOTES,
        payload: response.data
      })
    } catch (error) {
      console.log(error.response);
    }
  }

  const addNote = async data => {
    try {
      const response = await clientAxios.post('/addNote', data);
      dispatch({
        type: ADD_NOTE,
        payload: response.data.data
      })
    } catch (error) {
      console.log(error.response);
    }
  }

  const updateNote = async (id, { title, description }) => {
    try {
      const response = await clientAxios.put(`updateNote/${id}`, { title, description });
      console.log(response.data);
      dispatch({
        type: UPDATE_NOTE,
        payload: response.data
      })
    } catch (error) {
      console.log(error.response)
    }
  }

  const deleteNote = async id => {
    try {
      await clientAxios.put(`/deleteNote/${id}`);
      dispatch({
        type: DELETE_NOTE,
        payload: id
      })
    } catch (error) {
      console.log(error.response);
    }
  }

  return(
    <NoteContext.Provider
      value={{
        notes: state.notes,
        noteError: state.noteError,
        getNotes,
        addNote,
        updateNote,
        deleteNote,
      }}
    >
      {children}
    </NoteContext.Provider>
  );
}
 
export default NoteState;

还有我的减速机:

import {
  GET_NOTES,
  ADD_NOTE,
  DELETE_NOTE,
  UPDATE_NOTE,
} from '../../types';
export default (action, state) => {
  switch(action.type) {
    case GET_NOTES:
      return {
        ...state,
        notes: action.payload
      }
    case ADD_NOTE:
      return {
        ...state,
        notes: [...state.notes, action.payload]
      }
    case UPDATE_NOTE:
      return {
        ...state,
        notes: state.notes.map(note => note._id === action.payload._id ? action.payload : note)
      }
    case DELETE_NOTE:
      return {
        ...state,
        notes: state.notes.filter(note => note._id !== action.payload),
      }
    default:
      return state;
  }
}

【讨论】:

    猜你喜欢
    • 2021-12-04
    • 2021-03-07
    • 2020-03-28
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多