преобразованный класс в крючки, получающий свойство «тогда» не существует в типе » (отправка: любая) => Обещание>»

#javascript #reactjs #typescript #function #react-hooks

Вопрос:

Я новичок в крючках react, здесь преобразование из класса(версия класса работает) в крючки, я не уверен, правильно ли я это сделал, потому что при использовании «тогда» в крючках говорится «Свойство», затем «не существует типа» (отправка: любая) => Обещание». ts(2339)»

это версия класса, которая работает:

 import {
    getGraph,
    getFloorplan,
    changeActiveCamera,
} from "../redux/actions";

const mapStateToProps = (state) => {
  return {
    currentSite: state.selection.currentSite,
    currentCamera: state.selection.currentCamera,

  
  };
};

function mapDispatchToProps(dispatch) {
  return {
    getGraph: (site) => dispatch(getGraph(site)),
    getFloorplan: (site) => dispatch(getFloorplan(site)),
       changeActiveCamera: (site, id) => dispatch(changeActiveCamera(site, id)),

  };
}


loadGraph() {
    if (this.props.currentSite) {
      this.props.getFloorplan(this.props.currentSite.identif).then(() => {
        console.log("Fetched floorplan");

        this.props.getGraph(this.props.currentSite.identif).then(() => {
          console.log("Fetched model", this.props.realGraph.model);

          // new camera-related node amp; link status
          if (this.props.currentCamera) {
            this.props.changeActiveCamera(
              this.props.currentSite.identif,
              this.props.currentCamera.identif
            );
          }
        });
      });
    }
  } 

это то, что я сделал, чтобы преобразовать его :

   const dispatch = useDispatch();
  const currentSite = useSelector((state) => state.selection.currentSite);
  const currentCamera = useSelector((state) => state.selection.currentCamera);


const loadGraph = () => {
    if (currentSite) {
      dispatch(getFloorplan(currentSite.identif)).then(() => {
        console.log("Fetched floorplan");

        dispatch(getGraph(currentSite.identif)).then(() => {
          console.log("Fetched model", realGraph.model);

          // new camera-related node amp; link status
          if (currentCamera) {
            dispatch(
              changeActiveCamera(
                currentSite.identif,
                currentCamera.identif
              )
            );
          }
        });
      });
    }
  }; 

После просмотра видео, опубликованного в комментарии, я изменил код и получил новую ошибку: «Ошибка в диапазоне: максимальный размер стека вызовов превышен
в getFloorplan»
мой код:

    const currentSite = useSelector((state) =>      state.selection.currentSite);
   const currentCamera = useSelector((state) => state.selection.currentCamera);
   const getFloorplan = (site) => dispatch(getFloorplan(site));
   const getGraph = (site) => dispatch(getGraph(site));
   const changeActiveCamera = (site, id) =>
    dispatch(changeActiveCamera(site, id));
  
  const loadGraph = () => {
    if (currentSite) {
      getFloorplan(currentSite.identif).then(() => {
        console.log("Fetched floorplan");

        getGraph(currentSite.identif).then(() => {
          console.log("Fetched model", realGraph.model);

          // new camera-related node amp; link status
          if (currentCamera) {
            changeActiveCamera(
              currentSite.identif,
              currentCamera.identif
            );
          }
        });
      });
    }
  }; 

Комментарии:

1. В оригинале getGraph есть обещание, которое означает, что вы можете использовать then . Во втором примере ( dispatch(getFloorplan(currentSite.identif)).then ) вы пытаетесь привязать then dispatch то, что не является обещанием. Я все еще не понимаю, почему вам нужно отправлять сообщения на каждом уровне.

2. @Andy если бы вы преобразовали этот класс в хуки, как бы вы его преобразовали ?

3. не должен ли redux обновить что-то в своем состоянии после того, как вы выполнили отправку? и ваш компонент должен быть подписан на новый контент?

4. Это видео может помочь.

5. @Andy вы имеете в виду вот так: const getFloorplan = (сайт) => отправка(getFloorplan(сайт)); const getGraph = (сайт) =>> отправка(getGraph(сайт)); и внутри loadGraph удаление отправки?

Ответ №1:

Я очень сомневаюсь, что это простое решение сработает, но вот мои предложения по рефакторингу.

Пожалуйста, обратите внимание, что способ, которым был написан ваш старый класс, не является рекомендуемым способом написания redux. Конечно, код будет работать, но, по мнению многих людей, это не «правильный» способ.

Рефакторинг ваших действий

Я бы предпочел, чтобы мой код был написан так :

Ваш компонент.tsx

 const currentSite = useSelector((state) =>      state.selection.currentSite);
   const currentCamera = useSelector((state) => state.selection.currentCamera);
   const dispatch = useDispatch();

  const loadGraph = () => {
     useEffect(() => {
       if(currentSite)
          getFloorPlan(currenSite.identif);
      
     }, [ dispatch, currentSite.identif])
// dispatch is in the dependency array to stop make eslinter complain, you can remove it if you want, others are used to control the number of renders
    
  };
 

Ваши действия.ts

 // assuming you are using redux-thunk here
const getFloorplan = ( site : YourType ) => async dispatch => {
  console.log("Fetched floorplan");
  // remove await if getImage is a sync function, try with await first and remove if it doesn't fit
  const response = await getImage(`api/graph/${site}/floorplan`, GET_FLOORPLAN);
  dispatch(getGraph(response))
}

const getGraph = (site : YourType) => async dispatch => {
   console.log("Fetched model", realGraph.model);
   // new camera-related node amp; link status
   if (currentCamera) {
      changeActiveCamera(currentSite.identif,currentCamera.identif);
   }
}

const changeActiveCamera = ( site: YourType, param: YourAnotherType ) => async dispatch => {
 // your logic here
}
 

Комментарии:

1. мой план getfloor выглядит примерно так : функция экспорта getFloorplan(сайт) { возвращает getImage( api/graph/${site}/floorplan , GET_FLOORPLAN); };

2. добавлены и обновлены

3. моя камера changeActiveCamera: функция экспорта Камера changeActiveCamera(сайт, камера) { возвращает getData( api/cameras/${site}/${camera} , CHANGE_CAMERA); } и моя камера getGrpah: функция экспорта getGraph(сайт) { возвращает getData( api/graph/${site} , GET_ГРАФЫ); };

4. и делая это, я получил следующее: Неперехваченная ошибка: Недопустимый вызов крючка. Крючки могут вызываться только внутри тела функционального компонента. Это может произойти по одной из следующих причин: 1. У вас могут быть несовпадающие версии React и средства визуализации (например, React DOM) 2. Вы можете нарушать правила хуков

5. я предполагал, что вы используете redux-think промежуточное программное обеспечение, мое решение не будет работать, если у вас не установлено это промежуточное программное обеспечение