Как использовать пользовательский хук с обработчиком событий? - PullRequest
1 голос
/ 15 октября 2019

Я создал пользовательский Hook, который получает данные с сервера, отправляет данные в хранилище и возвращает данные. Это полезно, если я хочу перечислить все комментарии в своем приложении, однако я хотел повторно использовать его в компоненте, где мне нужно получить все ответы на комментарии, и это должно происходить только при нажатии определенной кнопки.

Это ловушка внизу.

import { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";

const useFetch = (url, options, actionType, dataType) => {
  const [response, setResponse] = useState([]);

  const dispatch = useDispatch();
  useEffect(() => {
    (async () => {
      const res = await fetch(url);
      const json = await res.json();
      setResponse(json);
    })();
  }, []);

  useEffect(() => {
    dispatch({ payload: response, type: actionType });
  }, [response]);
  const data = useSelector(state => state[dataType]);

  return data;
};

export default useFetch;

Внутри моего компонента мне нужно получать ответы при нажатии кнопки

const ParentComment = ({ comment }) => {
  const handleShowMoreReplies = (e) => {
    e.preventDefault();

}
  let replies = useFetch(
    `/api/comment_replies?comment_id=${comment.id}`,
    null,
    "REPLIES_RECEIVED",
    "replies"
  );
  return (
    <div>
      <Comment comment={comment} />
      <div className="replies">
        {replies.map(reply => (
          <Comment key={reply.id} comment={reply} />
        ))}
          <a href="#" className="show_more" onClick={handleShowMoreReplies}>
            Show More Replies ({comment.replies_count - 1})
          </a>
      </div>
    </div>
  );
};

Если я помещаю useFetch вызов внутри обработчикаЯ думаю, что ошибка не может быть вызвана там, но мне нужно вызывать ее только при нажатии кнопки, поэтому я не знаю, есть ли способ реализовать это.

1 Ответ

1 голос
/ 15 октября 2019

Я думаю, у вас есть тонкие проблемы в вашем хуке useFetch

1.В вашем useEffect есть dep $ {url} и $ {actionType}, которые вам нужно определить.

2. Чтобы вызвать этот хук, нажав кнопку, вам нужно выставить setUrl следующим образом

const useFetch = ( initialUrl, options, actionType, dataType) => {
  const [url, setUrl ] = useState(initialUrl);

  const dispatch = useDispatch();
  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url);
        const data = await res.json();
        dispatch({ payload: data, type: actionType });
      } catch (error) {
       console.log(error);
      }
    };
    fetchData();
  }, [url, actionType]);

  const data = useSelector(state => state[dataType]);
  return [ data, setUrl ];
};

export default useFetch;

Затем, когда вы пытаетесь использовать этот хук, вы можете

const [data, fetchUrl] = useFetch(
  `/api/comment_replies?comment_id=${comment.id}`,
  null,
  "REPLIES_RECEIVED",
  "replies"
);

Затемкаждый раз, когда у вас есть кнопка, вы можете просто позвонить

fetchUrl(${yourUrl}). 

, чтобы ваш хук получал новый URL, который является депо вашего хука, и перерисовывал его.

Вот статья по теме https://www.robinwieruch.de/react-hooks-fetch-data

...