Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
72 views
in Technique[技术] by (71.8m points)

javascript - Dynamically load from API SVG via hooks ReactJs

I have a module that renders an svg. Before it, the module should check on authorization and if ok fetch the file from api via call with a token.

I have the next code

  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")
  }
}

And the problem I have here is "React Hook "useEffect" cannot be called inside a callback" but without using "useEffect" it fetchs the svg endlessly.

How I can solve the issue?

question from:https://stackoverflow.com/questions/65625738/dynamically-load-from-api-svg-via-hooks-reactjs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are not doing it right, if you do this the "react" way then the solution would look like this

....
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]);
......

Note, this solution is intended to give you an idea of how to do it, It might not work if you copy-paste the code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...