ReactJS Redux Асинхронные действия - PullRequest
0 голосов
/ 05 января 2020

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

export const uploadFile = (files) => async (dispatch) => {

dispatch({ 
    type: T.UPLOAD_REQUEST,
    payload:{UploadStatus:"InProcess"}
 });
axios.post(`${config.API_URL}/upload`, files)
    .then(res => {
        dispatch({ 
            type: T.UPLOAD_SUCCESS, 
            payload: { UploadResponse: res.data,UploadStatus:"Completed"} 
        });
    }).then(res=>{

        dispatch({ 
            type: T.UPLOAD_SUCCESS, 
            payload: { UploadResponse: null,UploadStatus:"Queued"} 
        });

    })
    .catch(err =>{
        console.log(err);
        dispatch({ 
            type: T.UPLOAD_FAIL, 
            payload: { UploadResponse: err,UploadStatus:"Error" } 

        });
    }
    ).then(res=>{

        dispatch({ 
            type: T.UPLOAD_FAIL, 
            payload: { UploadResponse: null,UploadStatus:"Queued"} 
        });

    })
};

это действие загружает файл на сервер и отправляет редуктору для обновления в пользовательском интерфейсе. «UploadResponse» и «UploadStatus» - это два поля состояния, которые мне нужны для отображения пользовательского интерфейса на веб-интерфейсе.

при запуске запроса я устанавливаю {UploadStatus:"InProcess"} для рендеринга счетчика. После того, как запросы успешны или неуспешны, я устанавливаю эти поля состояния в «Завершено» или «Ошибка» соответственно. это помогает мне убрать счетчик и отобразить сообщение об успехе или неудаче.

, когда запрос завершается успешно, а UploadStatus имеет значение «Завершено», и на входной стороне появляется всплывающее сообщение об успешном завершении, и после этого пользователь взаимодействует с компонентом для повторной визуализации компонента. Допустим, я ввел некоторый текст в текстовое поле. Что происходит, если UploadStatus по-прежнему содержит значение «Completed», и снова появляется сообщение.

Чтобы решить эту проблему, я делаю 2 отправки для каждого успешного или неудачного ответа на запрос. например, вы можете видеть в приведенном выше коде, при успешном вызове я сначала отправил {UploadStatus:"Completed"}, а затем {UploadStatus:"Queued"}, чтобы сбросить статус. это помогает мне таким образом, что при первой отправке я отображаю сообщение об успехе на экране, а затем сбрасываю состояние загрузки, чтобы сообщение не появлялось при дальнейших взаимодействиях с компонентом.

Но я должен визуализировать div на внешнем интерфейсе, когда UploadStatus установлен на завершения, и этот div должен присутствовать даже после дальнейших действий с компонентом. Во время моей второй отправки UploadStatus был установлен в «Queued», поэтому div исчез.

Я добавлю код компонента ниже, чтобы объяснить мои логики c для визуализации пользовательского интерфейса

render() {
  return (
  <div>
   <div className="upload-sect">
   {
      this.props.UploadStatus=="InProcess"?<Spin/>: <></>
      this.props.UploadStatus=="Completed"? 
      this.rendermessage("success","uploded"):<></>
      this.props.UploadStatus=="Error"?this.rendermessage("error","Upload 
      Fail"):<></>
   }
  </div>
  <div>
    {
      this.props.UploadStatus=="Completed"?
      this.renderUploadResponse(this.props.UploadResponse)
      :
      <></>
    }
</div>
</div>)}

Ниже приведена функция отображения моего сообщения

//message is ANTD design control , which pops up message on screen for a 
//while and hides automatically 
rendermessage=(type,displaymessage)=>{

    if(type=="success"){
        message.success(displaymessage)
    } else if(type=="error"){
        message.error(displaymessage)
    }
}

Я использовал сообщение Antd для всплывающего сообщения на экране, которое автоматически скрывается по истечении заданного времени. https://ant.design/components/message/

Итак, что мне здесь не хватает, так это того, что я не могу найти правильный способ визуализации пользовательского интерфейса на веб-интерфейсе на основе изменения состояния.

я бы обработал этот сценарий просто без избыточности, как там, у меня был бы метод для отправки запроса внутри моего компонента, а внутри там, в случае успешного или неудачного ответа, я бы отправил сообщение прямо оттуда, вместо установки состояние, а затем рендеринг сообщения на основе состояния.

как показано ниже

 uploadFile=(files) =>{
 this.setState({UploadResponse: null,UploadStatus:"InProcess"});
 axios.post(`${config.API_URL}/upload`, files)
 .then(res => {
    this.rendermessage("success","File uploaded successfully.");
    this.setState({UploadResponse: res.data,UploadStatus:"Completed"});

 })
 .catch(err =>{
    this.rendermessage("fail","Failed to uploaded.");
    this.setState({UploadResponse: res.data,UploadStatus:"Completed"});
 }
 )
 }; 

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

  render() {
  return (
  <div>
   <div className="upload-sect">
   {
      this.props.UploadStatus=="InProcess"?<Spin/>: <></>
   }
  </div>
  <div>
    {
      this.props.UploadStatus=="Completed"?
      this.renderUploadResponse(this.props.UploadResponse)
      :
      <></>
    }
</div>
</div>)}

Что мне не хватает в Redux? Я думаю, что это очень распространенный сценарий, который происходит тысячи раз в реакции приложения. так что это должно быть так просто в обращении. чего мне не хватает, так это того, что я не могу найти стандартный способ использования redux?

Правильно ли я считаю, что ваша логика c для рендеринга компонента меняется, когда вы решаете использовать redux вместо управления состоянием на уровне компонента?

Можете ли вы предложить, что именно должно быть название этого вопроса?

Обновлено

Из раздела комментариев ниже я обнаружил, что большинство людей не понимают мой вопрос, поэтому мне нужно приложить больше усилий, чтобы быть более конкретным c.

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

Я показал, пока управляя состоянием на уровне компонентов, я просто работал с пользовательским интерфейсом очень просто. например, при успешном или неудачном асинхронном вызове я просто вызвал метод, который отображает всплывающее окно на экране, так что это всплывающее окно не было привязано к какому-либо изменению состояния, скорее оно отображалось непосредственно в результате действия. используете ли вы сообщение ANTD или любой другой провайдер уведомлений, который не имеет значения, дело в том, что оно должно исчезать автоматически (в соответствии с функциональностью провайдера уведомлений уведомление скрывается через определенный промежуток времени)

, поэтому в обычном режиме (i я звоню нормально на reactjs без избыточности) reactjs Я могу просто добиться такого поведения. например, обработать сообщение без какого-либо изменения состояния, и я автоматически исчезну.

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

Теперь, какое решение я принял, чтобы решить эту проблему, как показано ниже

Я пришел к выводу, что для того, чтобы справиться с избыточностью, мне нужно сделав две отправки для обработки сценария, я сделал небольшое изменение в своем коде, давайте разместим его ниже, чтобы вы, ребята, не прокручивали вверх, чтобы повторно посетить код

export const uploadFile = (files) => (dispatch) => {

dispatch({ type: T.UPLOAD_REQUEST,payload:{UploadStatus:"InProcess"}});
axios.post(`${config.API_URL}/upload`, files}).then(res => {            
dispatch({ type: T.UPLOAD_SUCCESS, payload: { UploadResponse:res.data,
UploadStatus:"Completed",MessageToBeDelievered:true} });
}).then(res=>{
dispatch({ type: T.UPLOAD_SUCCESS, 
        payload: { MessageToBeDelievered:false} 
    });
})
.catch(err =>{
    dispatch({ 
        type: T.UPLOAD_FAIL, payload: { UploadResponse:err,
         UploadStatus:"Error",MessageToBeDelievered:true }  
    });
}).then(res=>{

    dispatch({ type: T.UPLOAD_FAIL, 
    payload: {MessageToBeDelievered:false} 
    });

})
};

Так что никаких больших изменений, я просто оставьте дополнительный бит «MessageToBeDelievered» в первой отправке после успешного или неудачного вызова. MessageToBeDelievered имеет значение true, чтобы визуализировать всплывающее окно, а затем при следующей отправке он имеет значение false. довольно просто верно? Я не изменил UploadStatus во второй отправке, поэтому его значение остается «Завершено» после успешного вызова, даже после второй отправки. поэтому div, который мне нужно показать при успешном вызове, появляется и отдыхает там, если только UploadStatus снова не переходит в «InProcess».

Ничего страшного. Итак, снова возвращаясь к актуальному вопросу, мой вопрос

(i) Нужно ли мне по-другому думать о логи визуализации моего пользовательского интерфейса c, когда я использую Redux и не использую его? способ обработки состояния, и он не должен принадлежать логике рендеринга c моего компонента, но это заставляет меня думать, что рендеринг логики компонента c будет немного изменен, чего я не ожидал от избыточности.

(ii) Кроме этого всплывающего сообщения (которое скрывается автоматически), до сих пор я не смог найти другой сценарий, подобный этому, но есть ли другой сценарий ios, подобный этому? любой пример?

Ответы [ 2 ]

1 голос
/ 06 января 2020

Спецификация c Решение

В документации по ANTD Message упоминается аргумент onClose (функция), который можно передать в элемент управления.

Функция onClose, которую вы передаете, будет вызываться компонентом Message при закрытии после указанной вами продолжительности.

Вы должны передать функцию, которая обновляет свойство UploadStatus в ваше состояние притока к некоторому значению, отличному от «Завершено» (например, «Неактивно»).

Общие мысли

Вам не нужно использовать избыточность для всех состояний. Вполне допустимо смешивать состояние компонента с избыточностью. Я склонен использовать состояние компонента для хранения состояния, которое имеет отношение только к одному компоненту и его потомкам и / или является кратковременным состоянием. Я использую избыточность для состояния, которое используется несколькими компонентами и / или для более долгоживущего состояния.

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

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

0 голосов
/ 06 января 2020

С приставкой

Redux передает свойство UploadStatus в ваш компонент. При каждом рендеринге (нажатие клавиши и т. Д. c) вы выполняете рендеринг с помощью UploadStatus и соответствующего сообщения рендеринга ANTD. Это приводит к тому, что сообщение рендеринга запускается несколько раз, так как сообщение рендеринга используется неправильно.

Без избыточного числа

Не пропущена пропеллер, который будет визуализироваться повторно. Вы можете вызывать сообщение рендеринга ANTD только один раз после завершения функции.

У вас есть несколько вариантов решения этой проблемы.

  1. Не подключайте сообщение рендеринга АНТД к UploadStatus. Просто используйте его так, как вы уже настроили его без избыточности.
  2. Если вам нужно использовать избыточность, создайте отдельный компонент для его обработки и используйте React useEffect для запуска сообщения рендеринга.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...