首页 > 解决方案 > 通过钩子 ReactJs 从 API SVG 动态加载

问题描述

我有一个渲染 svg 的模块。在此之前,模块应检查授权,如果可以,则通过使用令牌调用从 api 获取文件。

我有下一个代码

  function App() {
  const [tableColors, setTableColors] = useState(["gray"]);
  const [svg, setSvg] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const [isErrored, setIsErrored] = useState(false);
  
  
  new AuthService().getUser().then(user =>{ if(!user) {
    Login()
  }
    else{
      useEffect( async () => {
        LoadSvg()
        .then(res => res.text())
        .then(setSvg)
        .catch(setIsErrored)
        .then(() => setIsLoaded(true))
      }, [])
    }})

  return ( 
    <div className="App">
      <header className="App-header">
       <SvgLoader svgXML={svg}>
       
      </SvgLoader> 
      
      </header>
    </div>
  );
  
  function Login(){
   var a = new AuthService();
   a.login();
  }

  async function LoadSvg(){
    return await new ApiService().callApi("https://localhost:44338/api/v1/desk-booking/Plan/getroomplanbyid?roomId=1")
  }
}

我在这里遇到的问题是“不能在回调中调用 React Hook “useEffect”,但如果不使用“useEffect”,它会无休止地获取 svg。

我该如何解决这个问题?

标签: javascriptreactjssvgfrontend

解决方案


您做得不对,如果您以“反应”方式执行此操作,则解决方案将如下所示

....
function App() {
  const [tableColors, setTableColors] = useState(['gray']);
  const [svg, setSvg] = useState(false);
  const [isLoaded, setIsLoaded] = useState(false);
  const [isErrored, setIsErrored] = useState(false);
  // state to check if user is loaded, used for svg call
  const [userLoaded, setUserLoaded] = useState(false);

  // useEffect does not prefer async function 
  useEffect(() => {
    if (!userLoaded) {
      new AuthService().getUser().then(user => {
        if (!user) {
          Login();
          // indicate user was loaded
          // I would move the login function body here instead since, login is async, so this might not work as intended but you get the idea
          setUserLoaded(true);
        }
      });
    }
  }, [])

  useEffect(() => {
    // if userLoaded is true then go ahead with svg loading
    if (userLoaded) {
      LoadSvg()
        .then(res => res.text())
        .then(setSvg)
        .catch(setIsErrored)
        .then(() => setIsLoaded(true));

    }
    // Add svg useEffect dependency on userLoaded
  }, [userLoaded]);
......

请注意,此解决方案旨在让您了解如何操作,如果您复制粘贴代码,它可能无法正常工作。


推荐阅读