2

I'm building a simple component that receives a word and send it backwards, then, it gets the new word, sends to a dictionary API and shows the result. I have created a isLoading state and error State. When i get a response different from 200, error should be true. But in my code, this is not happening. So, when i get a response different from 200, the code tries to render {dictionaryData.entry.sense[1].def} and crashes.

import React, { useState, useEffect, useRef } from "react";
import axios from "axios";
import "./App.css";

function App() {
  const [anagram, setAnagram] = useState("");
  const [anagramResult, setAnagramResult] = useState("");
  const [dictionaryData, setDictionaryData] = useState({});
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(false);

  const isFirstRun = useRef(true);
  useEffect(() => {
    if (isFirstRun.current) {
      isFirstRun.current = false; //i'm using useRef to not run this code on the first run
      return;
    }

    const fetchData = async () => {
      const result = await axios(
        `http://dicionario-aberto.net/search-json/${anagramResult}`
      );
      if (result.status === 200) {
        setDictionaryData(result.data);
        console.log(result.data);
        setIsLoading(false);
        setError(false);
      } else {
        setError(true);
        setIsLoading(true);
      }
    };
    fetchData();
  }, [anagramResult]);

  const reverseWord = word => {
    setAnagramResult([...word].reverse().join``);
  };

  return (
    <div className="App">
      <input
        type="text"
        name="anagram"
        onChange={e => setAnagram(e.target.value)}
        value={anagram}
      />
      <button onClick={() => reverseWord(anagram)}>Check Anagram</button>
      <p>result: {anagramResult}</p>
      {isLoading ? null : (
        <div>
          <p>Definições: {dictionaryData.entry.sense[1].def}</p>
          <p>{dictionaryData.entry.sense[2].def}</p>
          <p>{dictionaryData.entry.sense[3].def}</p>
        </div>
      )}
      {error ? <p>Houve um erro na pesquisa ou a palavra não existe.</p> : null}
    </div>
  );
}

export default App;

Sorry for any mistake, i'm just trying to understand hooks.

3
  • 1
    I haven't used axios, but I think if the server returns a non-200 code, it probably triggers an error which you need to handle in a catch clause, i.e., wrap the await in a try and catch any error, where you can set the error state on your component. For example see gist.github.com/fgilio/230ccd514e9381fafa51608fcf137253 Commented Oct 3, 2019 at 2:53
  • I think you are reversing word wrongly, you should try this setAnagramResult(word.split("").reverse().join("")); Commented Oct 3, 2019 at 3:55
  • @ravibagul91 could explain why? Commented Oct 3, 2019 at 12:24

1 Answer 1

1

I made some changes to your code.

I set isLoading default value to false, that makes more sense.

I wrapped "await axios" with try catch to handle all kind of errors.

Can you check please?

import React, { useState, useEffect, useRef } from "react";
import axios from "axios";
import "./App.css";

function App() {
  const [anagram, setAnagram] = useState("");
  const [anagramResult, setAnagramResult] = useState("");
  const [dictionaryData, setDictionaryData] = useState({});
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);

  const isFirstRun = useRef(true);
  useEffect(() => {
    if (isFirstRun.current) {
      isFirstRun.current = false; //i'm using useRef to not run this code on the first run
      return;
    }

    const fetchData = async () => {
      setIsLoading(true);

      try {
        const result = await axios.get(
          `http://dicionario-aberto.net/search-json/${anagramResult}`
        );
        setIsLoading(false);
        if (result.status === 200) {
          setDictionaryData(result.data);
          setError(false);
        } else {
          setDictionaryData({});
          setError(true);
        }
      } catch (error) {
        setDictionaryData({});
        setError(true);
        setIsLoading(false);
      }
    };
    fetchData();
  }, [anagramResult]);

  const reverseWord = word => {
    setAnagramResult([...word].reverse().join``);
  };

  return (
    <div className="App">
      <input
        type="text"
        name="anagram"
        onChange={e => setAnagram(e.target.value)}
        value={anagram}
      />
      <button onClick={() => reverseWord(anagram)}>Check Anagram</button>
      <p>result: {anagramResult}</p>
      {isLoading && <p>Loading...</p>}
      {!isLoading && dictionaryData.entry && (
        <div>
          <p>Definições: {dictionaryData.entry.sense[1].def}</p>
          <p>{dictionaryData.entry.sense[2].def}</p>
          <p>{dictionaryData.entry.sense[3].def}</p>
        </div>
      )}
      {error ? <p>Houve um erro na pesquisa ou a palavra não existe.</p> : null}
    </div>
  );
}

export default App;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.