我从不同的资料中读到,mobx优于反应渲染器,并且比redux更快.但是,如果我做了几个测试,它表明向mobx observables添加新数据非常慢.在反应原生环境中每毫秒都很重要并且使用解决方案很困难,即使循环超过200个元素和填充数组需要超过100毫秒因为我真的很喜欢mobx我希望有人可以看看测试代码并给我一些提示 - 我是什么我做错了,如何提高绩效.
import {observable, transaction,autorun} from 'mobx';
class Runner {
list = observable([]);
run() {
const start = new Date().getTime();
transaction(() => {
for (let i = 0; i < 200; i++) {
this.list.push({
id: observable(i),
one: observable('1'),
two: '2',
three: 3,
x: 'xxxxx',
y: 'yyyyy',
z: 'zzzzz',
z1: 'zzzzz',
z2: 'zzzzz',
z3: 'zzzzz',
z4: 'zzzzz',
});
}
});
console.log('Execution time: ' + (new Date().getTime() - start) + 'ms services ');
}
}
const runner = new Runner(); …Run Code Online (Sandbox Code Playgroud) 为什么MobX鼓励在文档中使用可变对象?
但是,我看到了有关MobX的教程:http ://orlandohamsho.com/javascript/mobx-react-tutorial-building-first-application/
而且,他在教程中使用了不变的方法,而不是使用可变方法(参见下文)。
@action setUsers = (users) => { this.users = [...users]; (而不是推动它)
我也认为不变性方法更好(这样React.PureComponent可以工作,这意味着优化性能)
为什么MobX鼓励对对象进行变异?我应该使用哪种方法?
标题几乎是自我解释的。我找不到任何关于它的信息。Angular 在幕后使用 RxJs observables 是不是在 React 和 MobX 中是一样的?
我有以下状态类:
import { observable, action } from 'mobx';
import axios from 'axios';
export default class AppState {
@observable user;
@observable pToken;
constructor() {
this.user = {};
this.pToken = localStorage.getItem('pToken');
}
async fetchData(query) {
const body = JSON.stringify({ query, });
const response = await axios.post('url', body, {
headers: {
'Content-Type': 'application/json',
token: localStorage.getItem('pToken')
}
});
const user = response.data.data.user;
console.log('Got user', user);
this.setUser(user);
}
@action setUser(user) {
this.user = user;
}
}
Run Code Online (Sandbox Code Playgroud)
在我的组件中:
@inject('store')
@observer
export default class Header extends Component …Run Code Online (Sandbox Code Playgroud) 我尝试访问我的组件中的一些引用.但我在控制台中有这个错误.
withRouter.js:44 Warning: Stateless function components cannot be given refs (See ref "pseudo" in FormInputText created by RegisterForm). Attempts to access this ref will fail.
这是我的组件:
class RegisterForm extends React.Component {
render() {
return (
<form action="">
<FormInputText ref="pseudo" type="text" defaultValue="pseudo"/>
<input type="button" onClick={()=>console.log(this.refs);} value="REGISTER"/>
</form>
);
}
}
Run Code Online (Sandbox Code Playgroud)
另外,当我点击Object {pseudo: null}控制台上的按钮时.我期待一个对象null.
我不确定为什么这不起作用.请注意我的反应树使用mobx-react.
如果我错了请纠正我,但目前使用replace是不可能的,因为替换会替换整个可观察数组,而应该使用map?
我有一个这样的可观察数组:
@observable questionsList = [];
Run Code Online (Sandbox Code Playgroud)
在服务器调用上,它将填充2个对象,每个对象都有一个不同的id字段,所以它看起来像这样:
@observable questionsList = [
{id: 1,
question: "Is the earth flats?",
answer: "Some long answer here..."
{id: 2,
question: "Does the moon have life?"}
answer: "Some long answer here..."}
];
Run Code Online (Sandbox Code Playgroud)
所以id的问题1有一个需要修复的拼写错误,应该是Is the earth flat?
鉴于以下内容:
const newQuestionId = 1;
const newQuestion = "Is the earth flat?"
const oldQuestion = this.questionsList.find(question => question.id === newQuestionId);
oldQuestion.replace(newQuestion) // Would be nice if this syntax worked
Run Code Online (Sandbox Code Playgroud)
现在我有正确的oldQuestion但我怎么能用questionList新问题在数组中替换它 …
使用Mobx,在更新商店(即单击按钮)后,组件不会重新呈现.我已经安装了mobx devtools,在初始加载后没有显示任何内容,并且控制台中没有错误.我做错了什么想法?
Store.js:
import { observable } from 'mobx';
class Store {
@observable me;
constructor() {
this.me = 'hello';
}
change_me(){
this.me = 'test 1234';
}
}
export default Store;
Run Code Online (Sandbox Code Playgroud)
layout.js:
import React from "react";
import { observer } from 'mobx-react';
@observer
export default class Layout extends React.Component{
render(){
return(
<div>
<h1>{this.props.store.me}</h1>
<button onClick={this.on_change}>Change</button>
</div>
)
}
on_change = () => {
this.props.store.change_me();
}
}
Run Code Online (Sandbox Code Playgroud)
index.js:
import React from "react";
import ReactDOM from "react-dom";
import Layout from "./components/Layout";
import Store …Run Code Online (Sandbox Code Playgroud) 我正在我的React Native应用程序中实现一个单词搜索工具.我有一个MobX商店wordStore.每个文本更改都会通过setFilter操作触发数据库查询.从控制台调试输出可以看出这一切都在幕后工作.
但是,WordList一旦触发任何更新,组件似乎就会消失,即如果我设置了一个默认的过滤字符串,它会显示列表中的匹配项,但是一旦任何文本更改它就会消失.
有什么我想念的吗?奇怪的是WordList.render()即使它不可见,该方法也会被执行.
编辑:渲染数组的.toString()方法从包含组件工作正常,但奇怪的是迭代数组也显示相同的行为,在更新时消失.
包含组件:
const WordSearch = observer(class WordSearch extends React.Component {
constructor(props) {
super(props);
}
render() {
let words = wordStore.getWords(); // For debugging
return (
<View>
<TextInput
style={styles.textInput}
onChangeText={(filter) => wordStore.setFilter (filter)}
value={wordStore.filter}
/>
<Text>{words.toString()}</Text> <!-- This works -->
<View style={{flex:1}} key={wordStore.filter}> <!-- This disappears too -->
{words.map((word, i) => {
console.log ('word: '+word);
return <View style={{flex:1}} key={i}>
<Text>{word}</Text>
</View>
})}
</View>
<WordList {...this.props} /> …Run Code Online (Sandbox Code Playgroud) 我正在使用 mobx/react 构建两个小部件,其中所有逻辑都位于商店内。两者共享大部分设计规则,因此他们的商店 95% 相同。有聪明的方法来处理这种情况吗?例如,是否可以创建这样的继承?
class Animal {
@observable name = "";
constructor(name) {
this.name = name;
}
@computed get sentence() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
@observable isBarking = false;
@computed get bark() {
if (this.isBarking){
console.log('The dog is barking');
}
}
@action
setIsBarking(isBarking) {
this.isBarking = isBarking;
}
}
Run Code Online (Sandbox Code Playgroud) 我收到了来自 Mobx 的警告信息。
[mobx.array] 尝试读取超出范围 (0) 的数组索引 (0)。请先检查长度。MobX 不会跟踪越界索引
@observable checks = {
deviceType: ['phone','laptop', ...],
deviceTypeChecks: [],
...
}
@action
selectAllChecks = (target, type) => {
const targetChecks = []
if (this.checks[target].length !== this.checks[type].length) {
this.checks[target].forEach(el => targetChecks.push(el))
}
this.checks[type] = targetChecks
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能删除那个警告?但是,这段代码没有问题。它运作良好。
我正在selectAllChecks通过 onChange 函数使用函数。
const {
deviceType,
deviceTypeChecks
} = this.props.store.checks
<label className="mr10">
<input
type="checkbox"
checked={deviceType.length === deviceTypeChecks.length}
onChange={() =>
selectAllChecks('deviceType', 'deviceTypeChecks')
}
/>
<span>All device type</span>
</label>
Run Code Online (Sandbox Code Playgroud)
我必须为 IE 提供 4 个版本。
"mobx": …Run Code Online (Sandbox Code Playgroud) mobx ×10
javascript ×6
mobx-react ×6
reactjs ×6
angular ×1
immutability ×1
mutable ×1
performance ×1
react-native ×1
rxjs ×1