为什么 useEffect 钩子在页面刷新时不起作用?

hak*_*gan 9 reactjs react-redux react-hooks use-effect

我正在做一个反应项目。我有自己的 API 来获取信息。我正在使用 useEffect 挂钩从 API 获取配置文件信息。我的问题是,当页面第一次安装时,我可以毫无问题地获取数据,但如果我刷新页面,它根本不起作用。我知道我必须为 useEffect 提供第二个参数。我尝试将配置文件作为第二个参数,甚至调度了 getCurrentProfile 函数,但是当我这样做时,它会不断地触发获取请求。如果有人能帮助我,我会很高兴。谢谢。

这是我的个人资料组件:

export const Profile = () => {
const dispatch = useDispatch();
useEffect(() => {
    dispatch(getCurrentProfile());

}, [])

const profileReducer = useSelector((state) => state.profile);
const authReducer = useSelector((state) => state.auth);
const { profile, error, loading } = profileReducer;



const { user } = authReducer;

console.log("loading", loading)
console.log("profile", profile)

return loading && profile === null ? (
    <div >
        <Spinner />
    </div>
) :
Run Code Online (Sandbox Code Playgroud)

这是我的个人资料操作:

export const getCurrentProfile = () => async dispatch => {

try {
    const res = await axios.get("/api/profile/me");
    console.log(res);
    dispatch({
        type: "GET_PROFILE",
        payload: res.data.data
    })
} catch (err) {
    dispatch({
        type: "PROFILE_ERROR",
        payload: { msg: err.response.statusText, status: err.response.status }
    })
}
Run Code Online (Sandbox Code Playgroud)

}

这是我的轮廓缩减器:

export default (state = initialState, action) => {
const { type, payload } = action;

switch (type) {
    case "GET_PROFILE":
        return {
            ...state,
            profile: payload,
            loading: false
        }

    case "PROFILE_ERROR":
        return {
            ...state,
            error: payload,
            profile: null
        }
    case "CLEAR_PROFILE":
        return {
            ...state,
            profile: null,
            loading: false
        }
    default:
        return state;
}
Run Code Online (Sandbox Code Playgroud)

}

Dak*_*nez 3

您可能想尝试在 useEffect 中添加条件逻辑,这样只有在您还没有配置文件时才触发调度。

\n
import "./styles.css";\nimport { useDispatch, useSelector } from "react-redux";\nimport { useEffect, useCallback } from "react";\nimport { getCurrentProfile } from "./action";\n\nexport const Profile = () => {\n  const dispatch = useDispatch();\n  const profileReducer = useSelector((state) => state.profile);\n  const authReducer = useSelector((state) => state.auth);\n  const { profile, error, loading } = profileReducer;\n  // read more about this here: https://stackoverflow.com/questions/58624200/react-hook-useeffect-has-a-missing-dependency-dispatch\n  const stableDispatch = useCallback(dispatch, []);\n\n  useEffect(() => {\n    if (!profile) {\n      stableDispatch(getCurrentProfile());\n    }\n  }, [profile, stableDispatch]);\n\n  const { user } = authReducer;\n\n  console.log("loading", loading);\n  console.log("profile", profile);\n\n  return loading && profile === null ? <div>Spinner</div> : "Actual Profile";\n};\n\nexport default Profile;\n\n
Run Code Online (Sandbox Code Playgroud)\n

另外,您目前似乎没有对loading状态\xe2\x80\x93 做任何事情,至少从您在这里分享的内容来看是这样。您可能希望在开始获取之前分派一个操作来指示您正在加载,然后在收到响应时将其设置为 false。

\n

查看此codesandbox以供参考:https://codesandbox.io/s/focused-kilby-gd2nr ?file=/src/App.js

\n

减速机:

\n
const initialState = {\n  profile: null,\n  loading: false\n};\nexport const profile = (state = initialState, action) => {\n  const { type, payload } = action;\n\n  switch (type) {\n    case "LOADING_PROFILE":\n      return {\n        ...state,\n        loading: true\n      };\n    case "GET_PROFILE":\n      return {\n        ...state,\n        profile: payload,\n        loading: false\n      };\n\n    case "PROFILE_ERROR":\n      return {\n        ...state,\n        error: payload,\n        profile: null\n      };\n    case "CLEAR_PROFILE":\n      return {\n        ...state,\n        profile: null,\n        loading: false\n      };\n    default:\n      return state;\n  }\n};\n\nexport const auth = (state = {}, action) => {\n  return state;\n};\n\n
Run Code Online (Sandbox Code Playgroud)\n

动作创建者:

\n
import axios from "axios";\nexport const getCurrentProfile = () => async (dispatch) => {\n  try {\n    dispatch({ type: "LOADING_PROFILE" });\n    const res = await axios.get("https://jsonplaceholder.typicode.com/users/1");\n    console.log(res);\n    dispatch({\n      type: "GET_PROFILE",\n      payload: res.data.data\n    });\n  } catch (err) {\n    dispatch({\n      type: "PROFILE_ERROR",\n      payload: { msg: err.response.statusText, status: err.response.status }\n    });\n  }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

索引.js

\n
import { StrictMode } from "react";\nimport ReactDOM from "react-dom";\nimport { Provider } from "react-redux";\nimport { createStore, combineReducers, applyMiddleware } from "redux";\nimport { profile, auth } from "./reducers";\nimport App from "./App";\nimport thunk from "redux-thunk";\n\nconst store = createStore(\n  combineReducers({\n    profile,\n    auth\n  }),\n  applyMiddleware(thunk)\n);\n\nconst rootElement = document.getElementById("root");\nReactDOM.render(\n  <StrictMode>\n    <Provider store={store}>\n      <App />\n    </Provider>\n  </StrictMode>,\n  rootElement\n);\n\n
Run Code Online (Sandbox Code Playgroud)\n