Javascript 在redux orm架构实例上使用reducer方法
我正在使用redux orm创建用于规范化和非规范化的模型。我发现,当我创建架构时,会出现以下错误:Javascript 在redux orm架构实例上使用reducer方法,javascript,reactjs,redux,redux-orm,Javascript,Reactjs,Redux,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' im
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
然而,我发现ReduxORM中模式的文档和代码仍然存在
如果我从
import { Schema } from 'redux-orm'
到
代码正常工作,但我收到一个错误,指定此处未定义reducer
方法:
import { schema } from './models'
console.log(schema)
const rootReducer = combineReducers({
orm: schema.reducer(),
selectedUserId: selectedUserIdReducer
})
大多数代码都是基于
我的模型是这样的:
验证模型.js
import { PropTypes } from 'react'
import { Model } from 'redux-orm'
import propTypesMixin from 'redux-orm-proptypes'
const ValidatingModel = propTypesMixin(Model)
export default ValidatingModel
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')
}
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
}
Todo.js
import { PropTypes } from 'react'
import { Model } from 'redux-orm'
import propTypesMixin from 'redux-orm-proptypes'
const ValidatingModel = propTypesMixin(Model)
export default ValidatingModel
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')
}
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
}
Tag.js
import { PropTypes } from 'react'
import { Model } from 'redux-orm'
import propTypesMixin from 'redux-orm-proptypes'
const ValidatingModel = propTypesMixin(Model)
export default ValidatingModel
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')
}
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
}
就我从您的代码中所见,您似乎错过了在模型中定义减速器的代码
(TODO、TAG、USER)
根据文件
每个模型中需要有一个静态方法
静态减速器(状态、动作、标记)
静态减速器(状态、动作、TODO)
静态缩减器(状态、操作、用户)
首先,我需要使用ORM
而不是模式。因此,我将Schema
的导入更改为:
import { ORM as Schema } from 'redux-orm'
其次,我必须将减速器的签名更改为:
static reducer (action, SessionSpecificModel, session)
redux orm文档已经更新,第二个参数不是reducer的状态,而是特定于会话的模型
根据文件中的签名:
static reducer (state, action, Model, session)
第三,我必须更改todo
中的代码,以使用toRefArray
或toModelArray
,以便在todo
和Tag
实例列表中调用map
:
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
})
第四,我必须从会话
实例解析模型
类
我仍然发现创建待办事项时存在问题,其中:
session.Todo.create(props)
抛出错误
:
提供给Todo.create的属性标记[0]
无效
使用道具调用时
:
{
"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中,在引导或创建模型时,可以向相关属性提供模型的id或实例。因此,有必要确保模型
接受这两种版本,以便进一步阅读从redux orm 0.8迁移到0.9的相关内容。请从开发人员处查看本指南:
github回购协议上的自述文件已经落后,但令人惊讶的是,npm自述文件更新为0.9,尽管0.9的PR尚未合并。
我将模型添加到问题中,您可以看到,我已为每个模型定义了减速器。