首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在redux-orm模式实例上使用约简方法

在redux-orm模式实例上使用约简方法
EN

Stack Overflow用户
提问于 2017-01-02 18:19:40
回答 3查看 1K关注 0票数 1

我正在使用redux-orm来创建规范化和反规范化的模型。我发现当我创建一个模式时,我会得到一个错误:

代码语言:javascript
复制
Uncaught Error: Schema has been renamed to ORM. Please import ORM instead of Schema from Redux-ORM

我使用了默认安装的0.90-rc1和`0.8.4

运行此代码时:

代码语言:javascript
复制
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中的模式文档和代码仍然存在。

如果我从

代码语言:javascript
复制
import { Schema } from 'redux-orm'

代码语言:javascript
复制
import { ORM as Schema } from 'redux-orm'

代码工作正常,但我在这里得到了一个错误,指定没有定义reducer方法:

代码语言:javascript
复制
import { schema } from './models' 

console.log(schema)

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

大部分代码是基于这里的底漆

我的模特长得像这样:

ValidatingModel.js

代码语言:javascript
复制
import { PropTypes } from 'react'
import { Model } from 'redux-orm'
import propTypesMixin from 'redux-orm-proptypes'

const ValidatingModel = propTypesMixin(Model)

export default ValidatingModel

Todo.js

代码语言:javascript
复制
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

代码语言:javascript
复制
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原始答案后,我添加了一个非op减缩器。

代码语言:javascript
复制
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
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-03 02:29:29

首先,我需要使用ORM而不是Schema。因此,我将Schema的导入更改为:

代码语言:javascript
复制
import { ORM as Schema } from 'redux-orm'

第二,我必须将减速机的签名改为:

代码语言:javascript
复制
static reducer (action, SessionSpecificModel, session)

redux-orm文档已经更新,第二个参数不是还原器的状态,而是会话特定的模型。

从文件中的签名:

代码语言:javascript
复制
static reducer (state, action, Model, session)

第三,我必须更改todo中的代码以使用toRefArraytoModelArray来调用TodoTag实例列表中的map

代码语言:javascript
复制
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时,我仍然会发现一些问题:

代码语言:javascript
复制
session.Todo.create(props)

抛出error

无效的支柱tags[0]提供给Todo.create

当使用props调用时

代码语言:javascript
复制
{
 "text":"Test my data",
 "tags":[
   "urgent",
   "personal"
  ],
  "user":0
}

验证似乎妨碍了模型的创建。在创建标记时,将PropTypes指定为:

代码语言:javascript
复制
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中,当引导或创建模型时,可以向相关属性提供模型的id或实例。因此,确保这两者都为Model所接受是不可能的。

票数 2
EN

Stack Overflow用户

发布于 2017-01-02 18:51:00

据我从您的代码中可以看出,您似乎忽略了在您的模型(TODO, TAG, USER)中定义还原器的代码。

根据文档这里

您需要在每个模型中有一个静态方法。

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

票数 0
EN

Stack Overflow用户

发布于 2017-01-04 22:35:30

有关从redux-orm 0.8到0.9的迁移的进一步阅读,请参阅开发人员的指南:https://github.com/tommikaikkonen/redux-orm/wiki/0.9-Migration-Guide

在github回购上的自述是落后的,但令人惊讶的是npm自述是更新到0.9,尽管PR为0.9尚未合并。https://www.npmjs.com/package/redux-orm

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41431573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档