Дождитесь завершения действия избыточности при использовании саги с избыточностью - PullRequest
0 голосов
/ 22 ноября 2018

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

// this.props.userOrders = []

dispatch(actions.createOrder(object))

doSomethingWith(this.props.userOrders)

Поскольку действие createOrder запускает сагу-редукт, который вызывает API,задержка, поэтому this.props.userOrders не обновляется до вызова моей функции doSomethingWith.Я мог бы установить тайм-аут, но это не похоже на устойчивую идею.

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

Вот другие соответствующие файлы:

actions.js

export const createUserOrder = (data) => ({type: 'CREATE_USER_ORDER', data})

Sagas.js

function * createUserOrder () {
  yield takeEvery('CREATE_USER_ORDER', callCreateUserOrder)
}

export function * callCreateUserOrder (newUserOrderAction) {
  try {
    const data = newUserOrderAction.data
    const newUserOrder = yield call(api.createUserOrder, data)
    yield put({type: 'CREATE_USER_ORDER_SUCCEEDED', newUserOrder: newUserOrder})
  } catch (error) {
    yield put({type: 'CREATE_USER_ORDER_FAILED', error})
  }
}

Api.js

export const createUserOrder = (data) => new Promise((resolve, reject) => {
  api.post('/userOrders/', data, {headers: {'Content-Type': 'application/json'}})
    .then((response) => {
      if (!response.ok) {
        reject(response)
      } else {
        resolve(data)
      }
    })
})

редуктор заказов:

case 'CREATE_USER_ORDER_SUCCEEDED':
   if (action.newUserOrder) {
      let newArray = state.slice()
      newArray.push(action.newUserOrder)
          return newArray
       } else {
       return state
   }

1 Ответ

0 голосов
/ 22 ноября 2018

Это похоже на XY Проблема .Вы не должны «ждать» внутри функции / обработчика событий жизненного цикла компонента, а использовать текущее состояние хранилища.

Если я правильно понимаю, это ваш текущий поток:

Вы отправляете действие CREATE_USER_ORDER в свой компонент React.Это действие используется вашей сагой callCreateUserOrder.Когда ваша сага создания ордера завершена, она отправляет другое «завершенное» действие, которое у вас уже есть, как CREATE_USER_ORDER_SUCCEEDED.

. Теперь вам нужно добавить подходящий редуктор / селектор для обработки вашего * 1014.*:

Это действие CREATE_USER_ORDER_SUCCEEDED должно быть обработано вашим редуктором для создания нового состояния, в котором заполняется некоторое свойство "orders" в вашем состоянии.Это может быть связано непосредственно с вашим компонентом через селектор, после чего ваш компонент будет перерисован и заполнен this.props.userOrders.


Пример:

компонент

class OrderList extends React.PureComponent {
  static propTypes = {
    userOrders: PropTypes.array.isRequired,
    createOrder: PropTypes.func.isRequired,
  }

  addOrder() {
    this.props.createOrder({...})
  }

  render() {
    return (
      <Wrapper>
        <Button onClick={this.addOrder}>Add Order</Button>
        <List>{this.props.userOrders.map(order => <Item>{order.name}</Item>)}</List>
      </Wrapper>
    )
  }
}

const mapStateToProps = state => ({
  userOrders: state.get('userOrders'),
})

const mapDispatchToProps = {
  createOrder: () => ({ type: 'CREATE_ORDER', payload: {} }),
}

export default connect(mapStateToProps, mapDispatchToProps)(OrderList)

редуктор

case 'CREATE_USER_ORDER_SUCCEEDED':
  return state.update('userOrders',
    orders => orders.concat([payload.newUserOrder])
  )

Если вам действительно нужны побочные эффекты, добавьте эти побочные эффекты квашей саги или создайте новую сагу, которая выполняет действие УСПЕХ.

...