Search code examples
pythonreactjsdjango-rest-frameworkapi-design

Prevent React Component From Calling API Endpoint Twice


I have a POST endpoint that creates an instance on the database once the user creates an account, the rows are filled with information like day of the week, date, user_id, etc.

@api_view(['POST'])
def generate_focus_instance_v2(request):
    try:
        user_id_from_request = request.data['user']
        if UserProgressReport.objects.filter(user=user_id_from_request):
            return Response({"message": "user instance already exists"})

        instance_serializer = UserProgressReportSerializer(data=request.data)
        if instance_serializer.is_valid():
            instance_serializer.save()
            return Response({"message": "user instance created", "data": instance_serializer.data})
        else:
            return Response({"message": "something went wrong", "data": instance_serializer.errors})
    except Exception as error:
        return Response({"message": str(error)})

Here is the React section of my code

  async function handleFocusInstanceCreation() {
    try {
      const response = await fetch(
        `http://127.0.0.1:8000/api/v1/create/focus_instance`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            user: currentUser.user_id,
            focus_time: 0.0,
            day_of_the_week: currentDayOfTheWeek,
            date: currentDate,
            week_number: currentWeekNumber,
          }),
        }
      );

      const data = await response.json();
      console.log(data);
    } catch (error) {
      throw new Error(error);
    }
  }


useEffect(() => {
    if (currentUser && currentUser.user_id) {
      handleFocusInstanceCreation();
      console.log("Focus Instance creation called");
    } else {
      console.log("not logged");
    }
  });

The code logic is working as I intended, but because of the double rendering problem of react, my component is being called two times, and that is leading to creating two instances on the database for the same user.

In other words, once the user is redirected to the Home component after creating an account I see two response messages from the API call.

After some research and testing, I know that if I remove the <React.StrictMode> tag my problem goes away, but I don't know the long-term implications of doing that. (Im kind new to react)

So my question is: should I remove the <React.StrictMode> tag or should I add a feature that limits to one the number of times that my endpoint will be called?


Solution

  • You're using useEffect without any dependencies, which means the side-effect code there will be called every time the component re-renders (and indeed, twice (or more – React is at liberty of doing that!) if using strict mode).

    You very probably don't want to use useEffect for data submission anyway; just do it when the user has entered the data and hits a submit button or whatnot.

    You could (and maybe should) also make your API and/or data model resilient against this: e.g. add unique-together constraints for user-date pairs, or whatever makes sense; in real life your users will double-click that save button.