带有 useContext 钩子的 useReducer 行为怪异,并且运行和无限循环

时间:2021-06-27 04:02:36

标签: javascript reactjs

我正在尝试制作一个从 API 获取数据的 React 项目,并且我正在尝试将 useReducer 钩子与来自外部文件的 useContext 结合使用。 文件夹结构:

  • 公开
  • src(在 src 文件夹中,我有 context.js 和 reducer.js 以及其余的组件和其他文件)
  • package.json

reducer.js:

    const reducer = (currentState, action)=>{
    switch(action.type){
        case 'setBreedList':
            // console.log('setBreedList ran')
            return {...currentState, breedList: [...currentState.breedList, action.payload]}
            // return currentState
            // return {...currentState.breedList, action.payload}
        default:
            return currentState
    }
}
export default reducer

context.js

import React, {useContext, useReducer} from 'react';
import reducer from './reducer';

const AppContext = React.createContext();

const initalState = {
    breedList: [],
    imageList: []
}

const AppProvider = ({children})=>{
    const [state, dispatch] = useReducer(reducer, initalState);

    const fetchAllBreeds = ()=>{
        fetch('https://dog.ceo/api/breeds/list/all')
            .then(res=>res.json())
            .then(data=>dispatch({type: 'setBreedList', payload: data}))
    }

    return (
        <AppContext.Provider value={{...state, fetchAllBreeds}}>
            {children}
        </AppContext.Provider>
    )
}

export const useGlobalContext = ()=>{
    return useContext(AppContext)
}

export {AppContext, AppProvider}

这是 index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {AppProvider} from './utils/context';

ReactDOM.render(
  <React.StrictMode>
    <AppProvider>
      <App />
    </AppProvider>  
  </React.StrictMode>,
  document.getElementById('root')
);

最后,这是 Input.jsx,我在其中调用 fetchAllBreeds 函数:

import React from 'react'
import {useGlobalContext} from '../utils/context'

const Input = () => {
    const {state, fetchAllBreeds} = useGlobalContext();
    fetchAllBreeds();
    console.log('hello')
    return (
        <div>
            <p>hello</p>
        </div>
    )
}

export default Input

现在,当我尝试调用上面 Input.jsx 文件中的 fetchAllBreeds 函数时,它会在控制台上无休止地打印“你好”。我不明白为什么会这样,我尝试了一些不同的方法,但结果是一样的。感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

main 组件正在调用 #include <stdio.h> #include <stdlib.h> #include <string.h> int reallocmem(int *p, size_t newsize) { printf("%p\n", &p); void *q; q = realloc(p, newsize); if (q != NULL) { p = q; return 1; } return 0; } int main(void) { int *p = 0x0; printf("%p\n", &p); if (!reallocmem(p, 10 * sizeof(int))) { fprintf(stderr, "Could not reallocate memory\n"); } int i; int size = 10; for (i = 0; i < size; i++) { p[i] = i * 2; } for (i = 0; i < size; i++) { printf("%d\n", p[i]); } free(p); } 函数,该函数将更新上下文值,进而重新渲染 Input 组件,因此 fetchAllBreeds 将重新运行。不要在组件体内调用任何会导致重新渲染的方法。

Input 组件内使用 fetchAllBreeds 钩子。只会执行一次。

useEffect