簡體   English   中英

如何在功能性 React 組件中修改 function 調用中的變量

[英]How to modify variable in function call in functional React component

export default function TopNav() {
  const ns = 'header';
  const { t, i18n } = useTranslation(ns);
  const data = getData(i18n.language, ns);

  var topNav = [];

  const parseData = () => {
    data.then((json) => {

      const headerArray = mkNumArray(json, 'row1');
      var topNav = headerArray.map((i) => {
        const url = t("row" + i + ".button" + i + ".url");
        const label = t("row" + i + ".button" + i + ".label");
        return (
         <a href={url}>{label}</a>
       );
      })
      console.log(topNav);
    });
  };

  parseData(topNav);
  console.log(topNav);

  return(
     ....
  )
}

我無法弄清楚如何處理這個導航變量。 由於 getData 中的異步請求,我希望在此 parseData function 中設置變量,但隨后希望它可用於在組件中返回。 ParseData里面的控制台日志是正確的,但是return之前的那個是空的。 最好的方法是什么?

這里定義了一些外部函數,但我認為它們不相關。

不要使用變量作為topNap,而是使用“狀態變量”之類的東西。 我的意思是,在里面使用類似 setState 的東西:

...
const me = this;

const parseData = () => {
    data.then((json) => {

      const headerArray = mkNumArray(json, 'row1');
      var topNav = headerArray.map((i) => {
        const url = t("row" + i + ".button" + i + ".url");
        const label = t("row" + i + ".button" + i + ".label");
        return (
         <a href={url}>{label}</a>
       );
      })

      me.setState(stateTopNavVar, topNav);
      console.log(topNav);
    });
  };

有時使用 react 還需要使用 setState 回調。 好吧,這取決於你是否使用 React 類。 請記住,變量為 state 變量是 React 用來在 React 虛擬 DOM 上傳播更改的方法

您應該閱讀useStateuseEffect

常見的流程是這樣的:讓topNav成為您組件的 state。 它的初始值可能為空。 第一次渲染后,會觸發parseData並設置topNav的值,從而觸發使用新值topNav重新渲染組件。

您的代碼可能如下所示:

export default function TopNav() {

  const [topNav, setTopNav] = useState([]);

  useEffect(()=>{
    const parseData = () => {
     data.then((json) => {

      // ** do logic...
      
      setTopNav(/*value of topnav*/);
     });
    };

  }, []);

 
  return(
     ....
  )
}

最好的方法是修改getData以使其返回一個值,而不是 promise。 或者您可以創建一個自定義掛鈎來為您完成此操作。 就像那是更“反應”的方式。 接下來 - 不要像以前那樣聲明變量和執行函數。 對於狀態 - useStateuseMemo 對於函數調用 - useEffect

自定義掛鈎:

function useGetData(param1, param2) {
  // undefined = not loaded or error
  // null = empty response
  const [data, setData] = useState(undefined);
  const dataPromise = useMemo(() => {
    return getData(param1, param2);
  }, [param1, param2]);

  useEffect(() => {
    setData(undefined);
    if (!dataPromise) return;
    dataPromise
      .then((res) => setData(res || null))
      .catch((e) => {
        console.error(e);
        setData(undefined);
      });

    return () => setData(undefined);
  }, [dataPromise]);

  return data;
}

用法:


function TopNav() {
  const ns = "header";
  const { t, i18n } = useTranslation(ns);
  const data = useGetData(i18n.language, ns);

  const topNav = useMemo(() => {
    if (!data) return [];

    const headerArray = mkNumArray(json, "row1");
    return headerArray.map((i) => {
      const url = t("row" + i + ".button" + i + ".url");
      const label = t("row" + i + ".button" + i + ".label");
      return <a href={url}>{label}</a>;
    });
  }, [data]);

  return <> what you had here </>;
}

暫無
暫無

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

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