Как заставить приложение реагировать на условное прослушивание хранилища избыточности?

У меня есть приложение React для управления университетами.

Ниже мой роутер:

<Route path="selecting/" component={SelectUniversity}>
    <Route path="myUniversity" component={MyUniversity} />
    <Route path="studentdetails" component={AddStudentDetails} />
    <Route path="payment" component={Payment} />
</Route>

поток ==>MyUniversity==>AddStudentDetails==>Payment. Согласно этому, все работает так, как ожидалось. Все три компонента MyUniversity, AddStudentDetails, Payment широко используют хранилище резервных копий. сильный>

mapStateToProps MyUniversity выглядит следующим образом.

function mapStateToProps(state) {
  const { results } = state.results

  const studentData = state.results.studentData
  return {
    results,
    studentData,
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ ...Actions, ...studentActions }, dispatch)
}

задействовано много переменных хранилища, это для примера. Точно так же разделите mapstaetoprops и mapdispatchtoprops для двух других компонентов.

Теперь требование (по некоторым неизбежным причинам): -

если пользователь напрямую попадает на страницу myuniversity с таким идентификатором, как показано ниже: - http://mywebsite.com/myuniversity/9999, мне нужно получить данные, связанные с 9999 (которые я уже получаю) и выполнить тот же поток.

мой обновленный роутер

<Route path="selecting/" component={SelectUniversity}>
    <Route path="myUniversity" component={MyUniversity} />
    <Route path="myUniversity/:unidetails" component={MyUniversity} />
    <Route path="studentdetails" component={AddStudentDetails} />
    <Route path="payment" component={Payment} />
</Route>

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

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

Подход 2 Поэтому я придумал другой подход: 1. Определите новый редуктор. 2. После получения данных сохраните весь результат ajax в желаемом формате в состоянии. 3. Теперь перейдите к mapstatetoprops каждого из трех компонентов и добавьте условия на каждом каждом уровне пропса, независимо от того, получаете ли вы данные из предыдущего или текущего редьюсера.

например: допустим, я добавил еще один редуктор с именем universitydetails, тогда мой mapstatetoprops будет выглядеть примерно так

const { results } = state.results || state.universitydetails

const studentData = state.results.studentData || state.universitydetails.studentData

return {
        results,
        studentData,
      }

затем снова добавляю условие на каждом уровне пропса (учитывая, что я использую 15-20 различных переменных состояния в каждом из трех компонентов)

Подход 3: добавить redux-saga и действие диспетчеризации при загрузке myuniversity и выполнить другие действия на его основе. Но это не будет общим. В случае, я хочу добавить подобную функцию для других вещей, таких как hostel, тогда мне снова нужно добавить саги для этих hostles и отправить действие при начальной загрузке.

Что я думаю, будет лучшим подходом (поправьте меня, если я ошибаюсь): - Определите новый редуктор и каким-то образом заставьте мой компонент слушать этот редуктор (например, подход 2, но без искажения кода), чтобы в случае я хочу добавить еще одну функцию, например hostelselector, мне просто нужно обновить мою новую структуру редуктора и заставить мой компонент слушать этот новый редуктор

Я застрял на как-то Любое предложение, как это сделать?


person user3677291    schedule 20.06.2017    source источник
comment
Итак, у вас есть страница (AddStudentDetails), которая будет получать данные из разных источников в зависимости от условия? Таким образом, у вас может быть n страниц, которые будут перетекать на одну и ту же (AddStudentDetails), и эта страница должна будет иметь возможность читать эти данные независимо?   -  person Ematipico    schedule 21.06.2017
comment
@Ematipico У нас есть n источников, которые попадут на компонент myuniversity, оттуда мне нужно поддерживать поток, например addsudentdetails, а затем оплату. Дайте мне знать, если у вас остались вопросы   -  person user3677291    schedule 21.06.2017


Ответы (1)


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

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

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

Структура ваших редукторов может быть такой:

=> myUniversity
      => currentSource
      => sources
            => uniDetails
            => hostel etc.

Вы можете создать такую ​​структуру, используя функцию combineReducers

// myUniversityReducer.js
import uniDetails from 'uniDetailsReducer'
import hostel from 'hostelReducer'
import currentSource from 'currentSourceReducer'

const sources = combineReducers({hostel, uniDetails})
const myUniversity = combineReducers({currentSource, sources})

export myUniversity

Внутри вашего mapStateToProps вы можете выбрать текущий источник:

function mapDispatchToProps = (state) => {
  const currentSource = selectCurrentSource(state) // currentSource = 'uniDetails' => name of the reducer
  const dataFromSource = selectDataFromSources(state, currentSource) // dataFromSource = state[currentSource] => object inside uniDetails

  // ... if here you need to manipulate data because the structure of every
  // source is different, you can have your function that will do that based on the source name

  return { ...dataFromSource }
}

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

person Ematipico    schedule 22.06.2017