David Pell
David Pell

Reputation: 939

ReactJS: Update List after delete or update query using useState

Im sort of new to react and my team wants to use useState, which functional components are much newer than using regular react components. There has been some debate about how to update a list that has been fetched, and a trigger has either deleting a record or refreshing a record and how to reflect that on the affected row. In this example we fetch list of subscriptions from db, render them into a list. The user clicks "unsubscribe" button, then we want that button to switch into a "Cancelled" Badge (in CancelledButton).

So my teammates say when executing a delete or update query you will have to refetch the data from the db to refresh the affected row. In this example I am passing isSubscribed into the useEffect array parameters to listen when there is a change and to call the code within when it does. I am setting it to true after the update query.

Question is there a better way to avoid having to refetch the data? Isn't react supposed to refresh the list automatically by keeping track of it in state?

function SubsSearchResults(props) {
  const [loading, setLoading] = useState(true);
  const [message, setMessage] = useState(null);
  const [isSuccess, setIsSuccess] = useState(false);
  const [cancelling, setCancelling] = useState(false);
  const [isSubscribed, seIsSubscribed] = useState(true);
  const [subscriptions, setSubscriptions] = useState([]);
  const [showWarning, setShowWarning] = useState(false);
  const [subId, setSubId] = useState("");
  const [showAlert, setShowAlert] = useState(false);
  const [searchType, setSearchType] = useState("date");
  const {
    match: { params }
  } = props;

  useEffect(() => {
    const fetchSubs = async () => {
      const api = new AdminAPI();
      let endpoint =
        params.type === "sub_id"
          ? `subscriptions/${params.term}`
          : `subscriptions/${params.type}/${params.term}`;

      const subscriptions = await api.sendGet(endpoint);

      if (subscriptions.success) {
        setLoading(false);
        setSubscriptions(subscriptions.body.subscriptions);
        msgSystem(null, null, false);
      } else {
        setLoading(false);
        msgSystem(subscriptions.error.message, false);
      }
    };
    fetchSubs();
  }, [props, params.type, params.term, isSubscribed]);

Upvotes: 0

Views: 1165

Answers (1)

CedFon
CedFon

Reputation: 81

Why not simply send a request to get subscriptions on mount, save the response inside state and then simply update this state when some action is executed?

const SubsSearchResults = ({ ...props }) => {
  const isMount = useRef(false);
  const [subscriptions, setSubscriptions] = useState([]);

  useEffect(() => {
    if (!isMount.current) {
      // Fetch subscriptions from server
      const fetchSubs = async () => {
        ...
        const subscriptions = await api.sendGet(endpoint);
        setSubscriptions([...subscriptions]);
        isMount.current = true;
        ...
      };
      fetchSubs();
    }
  }, [isMount]);

  const handleUnSubscribe = (e, subscriptionId) => {
    const newSubscriptions = subscriptions.map(subscription => {
      if (subscription._id === subscriptionId) {
        subscription.isActive = false;
      }
      return subscription;
    });
    setSubscriptions([...newSubscriptions]);
  };

  return (
    <div>
      {subscriptions.map(subscription => (
        // Your subscription item
        ...
        // Unsubscribe button
        {subscription.isActive ? (
           <button onClick={(e) => handleUnsubscribe(e, subscription._id)}>Unsubscribe</button>
        ) : (
          <CancelUnsubscribe onClick={(e) => handleCancelUnsubscribe(e, subscription._id)}>Cancel</CancelUnsubscribe>
        )}
      ))}
    </div>
  )
};

In this example I supposed that your subscription have all a unique id to manage subscriptions list. If you have to update server on unsubscribe, simply send request in the handleUnsubscribe.

handleCancelUnsubscription is not in the code, but it is mainly the opposite of handleUnsubscribe.

Now, your subscriptions list is supposed to keep its state without having to query subscriptions on each subscription modification.

I hope it can help you and I'm sorry if I made mistake.

Upvotes: 1

Related Questions