刚开始使用 Mobx 和 React,并且无法更新商店。单击按钮时出现错误,该按钮应更新“我”属性:
Store.js:12 Uncaught TypeError: Cannot set property 'me' of null
Run Code Online (Sandbox Code Playgroud)
我的店铺:
import { observable } from 'mobx';
class Store {
@observable me;
constructor() {
this.me = 'test';
}
change_me(){
this.me = 'test 1';
console.log(this); // null???
}
}
const store = new Store();
export default store;
Run Code Online (Sandbox Code Playgroud)
组件:
import React from "react";
import { observer } from 'mobx-react';
export default class Layout extends React.Component{
render(){
var store = this.props.store;
return(
<div>
<button onClick={store.change_me}>{store.me}</button>
</div>
)
}
}
Run Code Online (Sandbox Code Playgroud)
我可能错过了它如何工作的一些基本部分,但无法弄清楚。
最近我听说每个人都在谈论mobx,我在生产React Native应用程序中使用过(使用)Redux.
我只是想看看是否有人有这两方面的经验,并可以建议每个人在哪里拥有优势.
在mobx-react 文档中,store 的创建方式存在差异。例如,在React Context页面上:
在第一个代码示例中,商店使用 useLocalStore 实例化:
const store = useLocalStore(createStore)
Run Code Online (Sandbox Code Playgroud)
在第二个代码示例中,商店是通过直接“新建”商店来启动的:
counterStore: new CounterStore(),
themeStore: new ThemeStore(),
Run Code Online (Sandbox Code Playgroud)
通过推断,第一个是“本地”存储(因此需要 useLocalStore),第二个是“全局”存储,因此不需要。然而,目前尚不清楚这是为什么,以及随后的行为差异是什么。
为什么useLocalStore在第二个例子中不需要,这对 React 中的 store 和 mobx 的行为有什么不同?
感谢您提供任何意见
为什么MobX鼓励在文档中使用可变对象?
但是,我看到了有关MobX的教程:http ://orlandohamsho.com/javascript/mobx-react-tutorial-building-first-application/
而且,他在教程中使用了不变的方法,而不是使用可变方法(参见下文)。
@action setUsers = (users) => { this.users = [...users]; (而不是推动它)
我也认为不变性方法更好(这样React.PureComponent可以工作,这意味着优化性能)
为什么MobX鼓励对对象进行变异?我应该使用哪种方法?
我有一个用TypeScript编写的React应用程序(16.8.6),该应用程序使用React Router(5.0.1)和MobX(5.9.4)。导航正常运行并应在适当的时候加载数据,但是,当我单击浏览器的“后退”按钮时,URL会更改,但不会更新任何状态,并且页面也不会重新呈现。我已经阅读了有关此问题和withRouter修复的无数文章,我尝试了这些文章,但没有什么不同。
一个典型的用例是导航到摘要页面,选择导致加载新数据和推送新历史记录状态的各种操作,然后再返回几个步骤。大多数历史记录推送都发生在摘要组件中,该组件处理多个路由。我已经注意到,当从摘要页面返回到主页时,将按应有的方式进行重新渲染。
我的index.tsx
import { Provider } from 'mobx-react'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import App from './App'
import * as serviceWorker from './serviceWorker'
import * as Utils from './utils/Utils'
const rootStore = Utils.createStores()
ReactDOM.render(
<Provider {...rootStore }>
<App />
</Provider>,
document.getElementById('root') as HTMLElement
)
serviceWorker.unregister()
Run Code Online (Sandbox Code Playgroud)
我的app.tsx
import * as React from 'react'
import { inject, observer } from 'mobx-react'
import { Route, Router, Switch } from 'react-router'
import Home from './pages/Home/Home' …Run Code Online (Sandbox Code Playgroud) 我有以下状态类:
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) 使用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-react ×10
mobx ×9
reactjs ×6
javascript ×3
react-native ×2
immutability ×1
immutable.js ×1
mutable ×1
react-redux ×1
react-router ×1