Использовать метод редуктора в экземпляре схемы redux-orm

Я использую Redux-Orm для создания моделей для нормализации и денормализации. Я обнаружил, что при создании схемы я получаю сообщение об ошибке:

Uncaught Error: Schema has been renamed to ORM. Please import ORM instead of Schema from Redux-ORM

Я использовал оба 0.90-rc1 какая версия установлена ​​по умолчанию, а также `0.8.4

при запуске этого кода:

import { Schema } from 'redux-orm'
import Todo from './Todo'
import Tag from './Tag'
import User from './User'

const schema = new Schema()
schema.register(Todo, Tag, User)

export default schema

Однако я нахожу, что документация и код для схем в redux-orm все еще существуют.

Если я переключусь с

import { Schema } from 'redux-orm'

в

import { ORM as Schema } from 'redux-orm'

код работает, но я получаю сообщение об ошибке, указывающее, что reducer метод не определен здесь:

import { schema } from './models' 

console.log(schema)

const rootReducer = combineReducers({
  orm: schema.reducer(),
  selectedUserId: selectedUserIdReducer
})

Большая часть кода основана на учебнике

Мои модели выглядят так:

ValidatingModel.js

import { PropTypes } from 'react'
import { Model } from 'redux-orm'
import propTypesMixin from 'redux-orm-proptypes'

const ValidatingModel = propTypesMixin(Model)

export default ValidatingModel

Todo.js

import { fk, many } from 'redux-orm'
import { PropTypes } from 'react'
import ValidatingModel from './ValidatingModel'
import User from './User'
import Tag from './Tag'
import { CREATE_TODO, MARK_DONE, DELETE_TODO, ADD_TAG_TO_TODO, REMOVE_TAG_FROM_TODO } from '../actionTypes'
export default class Todo extends ValidatingModel {
  static reducer (state, action, Todo, session) {
    const { payload, type } = action
    switch (type) {
      case CREATE_TODO:
        const tagIds = payload.tags.split(',').map(str => str.trim())
        const props = Object.assign({}, payload, { tags: tagIds })
        Todo.create(props)
        break
      case MARK_DONE:
        Todo.withId(payload).set({ done: true })
        break
      case DELETE_TODO:
        Todo.withId(payload).delete()
        break
      case ADD_TAG_TO_TODO:
        Todo.withId(payload.todo).tags.add(payload.tag)
        break
      case REMOVE_TAG_FROM_TODO:
        Todo.withId(payload.todo).tags.remove(payload.tag)
        break
    }
  }
}

Todo.modelName = 'Todo'

Todo.propTypes = {
  id: PropTypes.number,
  text: PropTypes.string.isRequired,
  done: PropTypes.bool.isRequired,
  user: PropTypes.oneOf([PropTypes.instanceOf(User), PropTypes.number]),
  tags: PropTypes.arrayOf(PropTypes.oneOf([
    PropTypes.number,
    PropTypes.instanceOf(Tag)
  ]))
}

Todo.defaultProps = {
  done: false
}

Todo.fields = {
  user: fk('User', 'todos'),
  tags: many('Tag', 'todos')
}

Tag.js

import ValidatingModel from './ValidatingModel'
import { PropTypes } from 'react'
import { CREATE_TODO, ADD_TAG_TO_TODO } from '../actionTypes'

export default class Tag extends ValidatingModel {
  static reducer (state, action, Tag, session) {
    const { payload, type } = action
    switch (type) {
      case CREATE_TODO:
        const tags = payload.tags.split(',')
        const trimmed = tags.map(name => name.trim())
        trimmed.forEach(name => Tag.create(name))
        break
      case ADD_TAG_TO_TODO:
        if (!Tag.filter({ name: payload.tag }).exists()) {
          Tag.create({ name: payload.tag })
        }
        break
    }
  }
}

Tag.modelName = 'Tag'

Tag.backend = {
  idAttribute: 'name'
}

Tag.propTypes = {
  name: PropTypes.string
}

Это модель пользователя, я добавил неоперативный редуктор, увидев оригинальный ответ @squiroid

import ValidatingModel from './ValidatingModel'
import { PropTypes } from 'react'

export default class User extends ValidatingModel {
  static reducer (state, action, User, session) {
    return state
  }
}

User.modelName = 'User'

User.propTypes = {
  id: PropTypes.number,
  name: PropTypes.string
}

3 ответа

Решение

Во-первых, мне нужно было использовать ORM вместо Schema, Поэтому я изменил импорт для Schema чтобы:

import { ORM as Schema } from 'redux-orm'

Во-вторых, мне пришлось изменить сигнатуру редуктора на:

static reducer (action, SessionSpecificModel, session)

Документы Redux-Orm обновлены, вторым аргументом является не состояние редуктора, а конкретная модель сеанса.

из подписи в документации:

static reducer (state, action, Model, session)

В-третьих, мне пришлось изменить код в todo использовать toRefArray или же toModelArray для того, чтобы позвонить map в списке Todo а также Tag экземпляры:

return orm.Todo.filter({ user: userId }).toModelArray().map(todo => {
  const obj = Object.assign({}, todo.ref)
  obj.tags = todo.tags.toRefArray().map(tag => tag.name)
  return obj
})

В-четвертых, я должен был решить Model класс от session пример.

Я все еще нахожу проблемы с созданием Todo где:

session.Todo.create(props)

бросает error:

Неверная опора tags[0] поставляется в Todo.create,

когда вызывается с props:

{
 "text":"Test my data",
 "tags":[
   "urgent",
   "personal"
  ],
  "user":0
}

Проверки, кажется, мешают созданию модели. При создании тегов укажите PropTypes быть:

const { string, number, arrayOf oneOfType, instanceOf } = PropTypes
Todo.propTypes = {
   text: string,
   user: oneOfType([
      number,
      instanceOf(User)
   ]),
   tags: oneOfType([
      arrayOf(string),
      arrayOf(
        instanceOf(Tag)
      )
   ])
}

В redux-orm при начальной загрузке или создании моделей вы можете указать идентификатор или экземпляр модели для связанного свойства. Таким образом, было бы необходимо обеспечить, чтобы оба Model,

Насколько я вижу из вашего кода, кажется, что вы пропустили код определения редуктора в ваших моделях (TODO, TAG, USER),

Согласно документации здесь.

Вам нужно иметь один статический метод внутри каждой модели.

static reducer(state, action, Tag) static reducer(state, action, TODO) static reducer(state, action, USER)

Для получения дополнительной информации о переходе с redux-orm 0.8 на 0.9 ознакомьтесь с этим руководством разработчика: https://github.com/tommikaikkonen/redux-orm/wiki/0.9-Migration-Guide

README на репозитории github отстает, но на удивление npm README обновляется до 0,9, несмотря на то, что PR для 0,9 еще не слился. https://www.npmjs.com/package/redux-orm

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