簡體   English   中英

'useEffect' 不只運行一次

[英]'useEffect' not run only once


謝謝大家,尤其是 Mr.Drew Reese。 如果您像我一樣是新手,請參閱他的答案


我不知道為什么,但是當我使用useEffect控制台記錄狀態數據時,它總是會重新呈現,盡管狀態generalInfo沒有改變:/ 所以有人可以幫助我修復它並解釋我的錯誤嗎?

我想要的結果是數據將在generalInfo更改時更新。

非常感謝!

這是我的useEffect

========================問題在這里:

  const {onGetGeneralInfo, generalInfo} = props;
  const [data, setData] = useState(generalInfo);

  useEffect(() => {
    onGetGeneralInfo();
    setData(generalInfo);
  }, [generalInfo]);

=========================修復:

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

  useEffect(() => {
    setData(generalInfo);
  }, [generalInfo, setData]); 

這是mapStateToProps

const mapStateToProps = state => {
  const {general} = state;
  return {
    generalInfo: general.generalInfo,
  };
};

這是mapDispatchToProps

const mapDispatchToProps = dispatch => {
  return {
    onGetGeneralInfo: bindActionCreators(getGeneralInfo, dispatch),
  };
};

這是減速機

case GET_GENERAL_INFO_SUCCESS: {
        const {payload} = action;
        return {
          ...state,
          generalInfo: payload,
        };
      }

這是行動

export function getGeneralInfo(data) {
  return {
    type: GET_GENERAL_INFO,
    payload: data,
  };
}
export function getGeneralInfoSuccess(data) {
  return {
    type: GET_GENERAL_INFO_SUCCESS,
    payload: data,
  };
}
export function getGeneralInfoFail(data) {
  return {
    type: GET_GENERAL_INFO_FAIL,
    payload: data,
  };
}

這是傳奇

export function* getGeneralInfoSaga() {
  try {
    const tokenKey = yield AsyncStorage.getItem('tokenKey');
    const userId = yield AsyncStorage.getItem('userId');
    const params = {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${tokenKey}`,
      },
    };

    const response = yield call(
      fetch,
      `${API_GET_GENERAL_INFO}?id=${userId}`,
      params,
    );
    const body = yield call([response, response.json]);

    if (response.status === 200) {
      yield put(getGeneralInfoSuccess(body));
    } else {
      yield put(getGeneralInfoFail());
      throw new Error(response);
    }
  } catch (error) {
    yield put(getGeneralInfoFail());
    console.log(error);
  }
}

redux 中的初始狀態和組件中的狀態是一個空數組。 所以我想從 API 獲取數據。 我把它推到redux的狀態。 然后我用狀態它。 我想使用 useEffect 因為我想在 PUT 數據時更新狀態並在更新后更新本地狀態。

好的,所以我收集到您希望在組件掛載時獲取數據,然后在填充時將獲取的數據存儲到本地狀態。 為此,您需要將關注點分離到單獨的效果掛鈎中。 一個在組件掛載時分派一次數據獲取,另一個“監聽” redux 狀態的變化以更新本地狀態。 請注意,將傳遞的道具存儲在本地狀態中通常被認為是反模式。

const {onGetGeneralInfo, generalInfo} = props;
const [data, setData] = useState(generalInfo);

// fetch data on mount
useEffect(() => {
  onGetGeneralInfo();
}, []);

// Update local state when `generalInfo` updates.
useEffect(() => {
  setData(generalInfo);
}, [generalInfo, setData]);

在您的useEfect中,您正在設置generalInfo ,它會導致useEffect的依賴數組發生變化。 所以,它一遍又一遍地運行:

  useEffect(() => {
    onGetGeneralInfo();
    setData(generalInfo);
  }, [generalInfo]);

試試這個:

  useEffect(() => {
    onGetGeneralInfo();
    setData(generalInfo); // or try to remove it if it is unnecessary based on below question.
  }, []);

但是,我不明白您為什么使用setData(generalInfo); 在你之前設置過的useEffect中。 它在onGetGeneralInfo();中有變化嗎? 功能?

基於 React 18 的更新:

import { useEffect, useRef } from "react";

export default function Component() {
    const isRunned = useRef(false);

    useEffect(() => {
        !isRunned.current &&
            {
                /* CODE THAT SHOULD RUN ONCE */
            };

        return () => {
            isRunned.current = true;
        };
    }, []);

    return <div> content </div>;
}

Yow hook 擁有或使用了未在依賴項列表中列出的東西

useEffect(() => {
    onGetGeneralInfo();
    setData(generalInfo);
  }, [   onGetGeneralInfo, setData,   generalInfo]);

還要記住 useEffect 是在組件掛載之前和之后調用的,所以如果你添加一個日志,它將被打印出來

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM