有没有办法不预先在mobx状态树中定义数据模型?(以动态决定类型)



我希望能够不为数据模型定义类型,但在加载数据后仍然能够观察到数据。我也有关系,但它们可以静态定义。医生告诉我冷冻的情况,但我需要条目是可观察的。如果没有这些,我会更好地坚持我现在所拥有的。

我在下面的评论中读到了一些关于动态模型类型的内容:https://codeburst.io/the-curious-case-of-mobx-state-tree-7b4e22d461f但由于我还没有使用mst,也没有使用ts,所以没有足够的信息让我了解他的确切意思。

mst想让我做什么:

import React from "react";
import { render } from "react-dom";
import { types } from "mobx-state-tree";
import { observer } from "mobx-react";
const Todo = types.model({
name: types.optional(types.string, ""),
done: types.optional(types.boolean, false)
});
const eat = Todo.create({ name: "eat" });
render(
<div>
Eat TODO: {JSON.stringify(eat)}
</div>,
document.getElementById("root")
);

我想做的事:

import React from "react";
import { render } from "react-dom";
import { types } from "mobx-state-tree";
import { observer } from "mobx-react";
const Todo = types.model({});
const eat = Todo.create({ name: "eat" });
render(
<div>
Eat TODO: {JSON.stringify(eat)}
</div>,
document.getElementById("root")
);

更多信息:

https://github.com/mobxjs/mobx-state-tree/issues/326#issuecomment-433906949

https://github.com/mobxjs/mobx-state-tree/pull/247

这就是它在应用程序中的工作方式。它主要起作用,只是添加和删除项不会更新组件。

我想出了这个,它可以工作。它是在沙箱里做的。这是一项正在进行的工作。按原样,这是不起作用的,因为在初始化类型后不可能更改它们

在的帮助下https://egghead.io/lessons/react-create-dynamic-types-and-use-type-composition-to-extract-common-functionality

https://codesandbox.io/s/m39mjomzwx

import React, { Component } from "react";
import { types } from "mobx-state-tree";
import { observer } from "mobx-react";
import { render } from "react-dom";
const ModelActions = types.model({}).actions(self => ({
addToName: function addToName(string) {
self.name = `${self.name} ${string}`;
}
}));
function createModel(instance) {
return types.compose(
types.model(instance),
ModelActions
);
}
const TodoActions = types.model({}).actions(self => ({
toggle: function toggle() {
self.done = !self.done;
}
}));
function createTodoModel(todo) {
return types.compose(
TodoActions,
createModel(todo)
);
}
function fetchUsers() {
return Promise.resolve([{ id: 1234, name: "Jan" }]);
}
function fetchTodos() {
return Promise.resolve([
{ id: 5, name: "eat", done: false },
{ id: 1, name: "drink" }
]);
}
function createDataStore(userData, todoData) {
const User = createModel(userData[0]);
const Todo = createTodoModel(todoData[0]);
return types
.model({
users: types.map(User),
todos: types.map(Todo)
})
.actions(self => {
return {
addUser(user) {
self.users[user.id] = User.create(user);
},
removeUser(id) {
self.users.delete(id);
},
addTodo(todo) {
self.todos[todo.id] = Todo.create(todo);
}
};
});
}
function makeStore([userData, todoData]) {
const store = createDataStore(userData, todoData).create();
function addData(add, data) {
for (let i in data) {
add(data[i]);
}
}
addData(store.addTodo, todoData);
addData(store.addUser, userData);
return Promise.resolve(store);
}
const AppState = types.model({ selected: false }).actions(self => {
return {
select() {
self.selected = !self.selected;
}
};
});
const appState = AppState.create();
let dataState = null;
// works
const ThingNode = observer(function ThingNode({ thing }) {
return (
<span>
{JSON.stringify(thing)}
<br />
</span>
);
});
function* getThingList(things) {
for (let key in things) {
if (Number(key)) {
yield (
<ThingNode key={key} thing={things[key]} />
);
}
}
}
// does not add or remove items
const Child = observer(function Child({ state, store, ready }) {
return (
<div>
Users:
<br />
{store ? [...getThingList(store.users)] : null}
<br />
Todos:
<br />
{store ? [...getThingList(store.todos)] : null}
<br />
Selected:
<br />
{JSON.stringify(state.selected)}
<br />
Ready:
<br />
{JSON.stringify(ready)}
</div>
);
});
@observer
class Parent extends Component {
state = { ready: null };
componentDidMount() {
Promise.all([fetchUsers(), fetchTodos()])
.then(makeStore)
.then(state => {
dataState = state;
// this.setState({ ready: true });
this.props.store.select();
})
.then(() => {
// test some stuff
dataState.addTodo({ id: 789, name: "eat a cake" });
dataState.addUser({ id: 324, name: "Henk" });
dataState.users[324].addToName("Klaassie");
dataState.todos[1].addToName("haha");
dataState.todos[5].toggle();
setTimeout(() => {
dataState.removeUser(1234);
dataState.addTodo({ id: 90, name: "dinges" });
dataState.todos[5].addToName("thing");
}, 1000);
setTimeout(() => {
dataState.todos[789].addToName("hihi");
}, 2000);
setTimeout(() => {
dataState.todos[90].addToName("twice");
}, 4000);
})
.then(() => {
this.setState({ ready: false });
})
.then(() => {
// only now do the added / removed entries become visible
setTimeout(() => this.setState({ ready: true }), 3000);
});
}
render() {
console.log("Parent", dataState);
return (
<Child
store={dataState}
state={this.props.store}
ready={this.state.ready}
/>
);
}
}
render(<Parent store={appState} />, document.getElementById("root"));

相关内容

最新更新