anthino12
anthino12

Reputation: 978

React renders component many times when fetching data

I'm using fetch api so my goal is to fire a POST request and then store the result received from this call in a state. This is the code that I use:

interface IPreviewFile {
file: IFile;
}

export default function PreviewFileModal({ file }: IPreviewFile) {
  const source = useSelector((state: AppState) => state.source);
  const project = useSelector((state: AppState) => state.project);

  const data = {
    fileName: file.path,
    accountName: source.Name,
    bucket: source.bucket,
    id: source.id
  };

  useEffect(() => {
    Promise.all([
      fetch(`${API_URL}/api/project/${project.id}/filepreview`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      })
    ])
      .then(async ([aa]) => {
        const a = await aa.json();
        return [a];
      })
      .then((responseText) => {
        setStringArray(readString(responseText[0].value).data);
      })
      .catch((err) => {
        console.log(err);
      });
  }, [project.id, data]);

  console.log(stringArray);
  return (
    <>
      <div></div>
    </>
  );
}

The console.log(stringArray); prints in the console all the time after delay of 2-3 seconds. As you can see, I use Promise in order to avoid this but for some reason it still happens. Any ideas what causes the re-rendering all the time and how to fix it?

Upvotes: 1

Views: 577

Answers (1)

Antonio Pantano
Antonio Pantano

Reputation: 5062

I've tried changing the code a bit to avoid re-rendering the component due to the data variable added as a dependency to useEffect. I don't see any reference to stringArray, so i've added it as a state variable.

export default function PreviewFileModal({ file }: IPreviewFile) {
  const source = useSelector((state: AppState) => state.source);
  const project = useSelector((state: AppState) => state.project);
  const [stringArray, setStringArray] = useState("");

   useEffect(() => {
     
    fetch(`${API_URL}/api/project/${project.id}/filepreview`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        fileName: file.path,
        accountName: source.Name,
        bucket: source.bucket,
        id: source.id
      })
    })
    .then(res => res.json())
    .then((result) => {
      result && setStringArray(readString(result.value).data);
    })
    .catch((err) => {
      console.log(err);
    });
  }, [project.id]);

  console.log(stringArray);
  return (
    <>
      <div></div>
    </>
  );
}

Upvotes: 1

Related Questions