Мой код React-Redux запускает функции до того, как предыдущие функции могут завершиться

Как мне написать эти функции, чтобы отправка завершалась до запуска операторов if? В настоящее время операторы if запускают console.info() до того, как отправка может даже сохранить данные.

  const doStuff = () => {
    dispatch(getStuff()); // WAIT FOR ME TO COMPLETE BEFORE MOVING ON!!!
    
    if (stuff) {   //stuff is retreived from global state
      console.info("stuff available") //I WAITED FOR THE DISPATCH!
    }

    if (!stuff) {   //stuff is retreived from global state
      console.info("no stuff") //I WAITED FOR THE DISPATCH!
    }
  };

export const getStuff = () => { \\WAIT FOR ME TO SAVE STUFF!!!
  return (dispatch) => {
      axios.get(`/stuff`).then((response) => {
      dispatch({
        type: SAVE_STUFF_TO_STATE, //stuff is saved to global state
        payload: response.data, //stuff
      });
      })
    } catch (err) {
      console.info("stuff issue")
    }
  };
};

Как вещи «набиваются»?

MetallimaX 21.12.2020 23:57

@MetallimaX Материал сохраняется в состояние через редуктор.

twominds 22.12.2020 00:03

И как восстановить состояние?

MetallimaX 22.12.2020 00:06

@MetallimaX Материал извлекается из состояния с помощью useSelector.

twominds 22.12.2020 00:11

почему бы вам не использовать для этого useEffect?

buzatto 22.12.2020 01:13

@buzatto что это изменит? Я также пробовал это, и это ничего не дало, кроме создания дополнительных шагов.

twominds 22.12.2020 01:24

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

buzatto 22.12.2020 01:27

@buzatto Я только что попробовал, ничего не изменилось, как ожидалось.

twominds 22.12.2020 01:29

@buzatto Мой фактический код запускает оверлейное сообщение об ошибках. Во время функции doStuff(), если отправка завершается без ошибок, операторы if должны выполняться после. Если функция отправки сохраняет данные в состояние, то операторы if будут запускать наложение ошибок, если данных нет.

twominds 22.12.2020 01:33
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
9
275
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вернуть промис можно из функции, можно попробовать с помощью https://github.com/reduxjs/redux-thunk

enter code hereexport const getStuff = () => { \\WAIT FOR ME TO SAVE STUFF!!!
 return (dispatch) => {
    axios.get(`/stuff`).then((response) => {
      return Promise.resolve(
         // the actions to be dispatched goes here
      );
    })
  } catch (err) {
     console.info("stuff issue")
  }
 };
};

и дождитесь его выполнения,

 const doStuff = () => {
    dispatch(getStuff()).then(()=> { // WAIT FOR ME TO COMPLETE BEFORE MOVING ON!!!

      if (stuff) {   //stuff is retreived from global state
       console.info("stuff available") //I WAITED FOR THE DISPATCH!
      }

      if (!stuff) {   //stuff is retreived from global state
       console.info("no stuff") //I WAITED FOR THE DISPATCH!
      }
   });
 };

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

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

twominds 22.12.2020 08:48

Вам нужно вернуть обещание от getStuff: return axios.get(/stuff).then

HMR 22.12.2020 08:54

@HMR Я только что попытался добавить возврат к аксиомам, обещаниям и отправке по отдельности, ни один из них не сработал. Тот, который вы указали, сломал код, каким-то образом остановив функцию отправки в обещании. Остальные пришли с той же исходной ошибкой.

twominds 22.12.2020 09:06

@ user67 Я добавил рабочий пример, если вы не можете заставить его работать, предоставьте песочницу, демонстрирующую проблему.

HMR 22.12.2020 09:09

@HMR хорошо, спасибо, сейчас я смотрю и понимаю ваш пример.

twominds 22.12.2020 09:17

@user67. я предполагал, что вы используете преобразователь, так как вы использовали отправку при возврате внутри функции. Если вы этого не сделали, вам может понадобиться избыточный преобразователь, чтобы улучшить ваши функции для возврата действия.

Sasi Kumar M 22.12.2020 11:28

@SasiKumarM В моих модулях установлен redux-thunk. Я смотрю на альтернативные варианты, такие как сага. Кажется, что .then() ничего не возвращает. Спасибо.

twominds 22.12.2020 12:05

я забыл добавить возврат к обещанию. редукционный преобразователь определенно сработает в этом сценарии, stackoverflow.com/questions/35069212/…

Sasi Kumar M 22.12.2020 12:13

Ваша функция создания обещания должна возвращать обещание, и ваше действие thunk должно возвращать это обещание:

const { Provider, useDispatch, useSelector } = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;

const initialState = {
  status: 'initial',
};
//action types
const ONE = 'ONE';
const TWO = 'TWO';
//action creators
const later = (value, time = 2000) =>
  new Promise((resolve) =>
    setTimeout(() => resolve(value), time)
  );
const one = () => (dispatch) =>
  //return the promise here
  later()
    .then(() => dispatch({ type: ONE }))
    .then(() => later('the value one resolves with'));
const two = () => ({ type: TWO });
const reducer = (state, { type, payload }) => {
  if (type === ONE) return { ...state, status: 'one' };
  if (type === TWO) return { ...state, status: 'two' };
  return state;
};
//selectors
const selectStatus = (state) => state.status;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware(
      ({ dispatch, getState }) => (next) => (action) =>
        //basic thunk implementation
        typeof action === 'function'
          ? action(dispatch, getState)
          : next(action)
    )
  )
);
const App = () => {
  const dispatch = useDispatch();
  React.useEffect(() => {
    one()(dispatch).then((oneResolve) => {
      console.info('one resolved with:', oneResolve);
      dispatch(two());
    });
  }, [dispatch]);
  const status = useSelector(selectStatus);
  return <h1>Status:{status}</h1>;
};

ReactDOM.render(
  <Provider store = {store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id = "root"></div>

Другие вопросы по теме