繁体   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