1

I found one API which return a word, definition.

I want to display a word and definition and when the button is pressed it should refetch and show new word.

I wrote this code. But I can't make it work. I'm not sure what I'm doing wrong.

I don't wanna use Axios or any library

import React, { useEffect, useState, Button } from "react";

function RandomWord() {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false);

  useEffect(() => {
    fetch("https://rnd-word.vercel.app/word")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);

  return (
    <>
      <div class="App">
        {isLoading ? (
          <p>Loading...</p>
        ) : (
          <span
            data={data}
            keyExtractor={({ id }, index) => id}
            renderItem={({ item }) =>
            <p>{item.word}</p>
            <p>{item.defintion}</p>
          }
          />
        )}
      </div>
      <Button
        title="New Word"
        onPress={() => setRefetch(!refetch)}
        color="#e56b6f"
      />
    </>
  );
}

export default RandomWord;

5 Answers 5

1

A <span> html element doesn't have attributes like renderItem or keyExtractor. When you want to render the data you should map it to JSX.

data.map((item, index) => 
  <div key={index}>
      <p>{item.word}</p>
      <p>{item.definition}</p>
  </div>

You can also directly call a function that fetches the data, you don't have to trigger another rerender that just triggers the fetch.

function fetchNextWord(){
  setLoading(true);
  fetch("https://rnd-word.vercel.app/word")
    .then((response) => response.json())
    .then((json) => setData(json))
    .catch((error) => console.error(error))
    .finally(() => setLoading(false));
}

useEffect(fetchNextWord, []); // Initial load

You can run this example snippet:

const { useState, useEffect } = React;

function RandomWord() {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  
  function fetchNextWord(){
    setLoading(true);
    fetch("https://rnd-word.vercel.app/word")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }
  
  useEffect(fetchNextWord, []); // Initial load


  return (
    <div>
      <div className="App">
        {isLoading ? (
          <p>Loading...</p>
        ) : 
          data.map((item, index) => 
           <div key={index}>
               <p>{item.word}</p>
               <p>{item.definition}</p>
           </div>
          )
        }
      </div>
      <button
        onClick={fetchNextWord}
        color="#e56b6f"
        >New Word</button>
    </div>
  );
}

ReactDOM.render(<RandomWord />, document.getElementById("root"));
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Sign up to request clarification or add additional context in comments.

Comments

0

<span> tag in reactjs only show normal text. Not like FlatList in the react-native. So you should use map to render like this:

{
    isLoading ? (
        <p>Loading...</p>
    ) : (
        data.map((item, index) => (
            <div key={index}>
                <p>{item.word}</p>
                <p>{item.defintion}</p>
            </div>
        ))
    );
}

Comments

0

I would console.log(json) in your fetch. See if the data is being sent how you expect and populating data state correctly.

Comments

0

I can see that you're calling useEffect on changes to refetch, which is itself changed by the setFetch method, each time you call onPress on button

However, in a useState hook's state updation with respect to previous state, you have to specify in the updating function i.e. setFetch in this case that you want the new value obtained as a function of the previous value.

Hence, your change in code would be just this :

...
<Buttton
 onPress = setRefetch(prevRefetch => !prevRefetch)
...

Comments

0
import React, { useState, useEffect, Fragment } from "react";

let RandomWord = () => {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false);

  useEffect(() => {
    fetch("https://rnd-word.vercel.app/word")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);

  return (
    <div>
      <div class="App">
        {isLoading ? (
          <p>Loading...</p>
        ) : (
          <Fragment>
            {/* whole fetch data */}
            {JSON.stringify(data)}
            {data.map((item) => {
              return (
                <Fragment>
                  <p> {item.word} </p>
                  <p> {item.definition} </p>
                </Fragment>
              );
            })}
          </Fragment>
        )}
      </div>
      <button onClick={() => setRefetch(!refetch)} color="#e56b6f">
        Click Me
      </button>
    </div>
  );
};

export default RandomWord;

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.