我正在为MobX 看这个小提琴,我也看到了这两种在ES6其他地方定义React Components的方法,比如Dan Abramov的egghead redux视频系列.
@observer
class TodoListView extends Component {
render() {
return <div>
<ul>
{this.props.todoList.todos.map(todo =>
<TodoView todo={todo} key={todo.id} />
)}
</ul>
Tasks left: {this.props.todoList.unfinishedTodoCount}
</div>
}
}
const TodoView = observer(({todo}) =>
<li>
<input
type="checkbox"
checked={todo.finished}
onClick={() => todo.finished = !todo.finished}
/>
<input
type="text"
value={todo.title}
onChange={ e => todo.title = e.target.value } />
</li>
);
Run Code Online (Sandbox Code Playgroud)
我的问题是,什么时候适合使用每种类型?
似乎更简单的组件能够使用更简单的语法,但我希望遵循规则或准则.
谢谢!
我有客户表和所选客户存储在ViewState.问题是当选择发生变化时,所有行都会重新渲染,这很慢.理想情况下,只有选定的行和之前选择的行会重新渲染,但我没有找到如何实现这一点.我的结构与MobX联系人列表示例中的示例相同:
{this.filteredCustomers.map(customer => {
return (
<CustomerRow
key={customer.id}
customer={customer}
viewState={this.props.store.view}
/>
)
})}
Run Code Online (Sandbox Code Playgroud)
和
const CustomerRow = observer((props: CustomerRowProps) => {
const isSelected = props.viewState.isCustomerSelected(props.customer)
const rowClass = isSelected ? 'active' : ''
return (
<tr className={rowClass}>
<td>{props.customer.lastName}</td>
<td>{props.customer.firstName}</td>
</tr>
)
})
Run Code Online (Sandbox Code Playgroud)
所有行都取决于ViewState.selectedCustomer通过该isCustomerSelected方法的值.
有没有其他方法来构建这个避免重新渲染所有行?
我试图让 MobX 在反应中使用功能组件。我想这样做而不必使用装饰器。我已经使用 create-react-app 设置了一个应用程序,添加了 MobX 和 MobX-react 作为依赖项。但是,我似乎无法在功能组件中使用 observable。
import React from 'react';
import { extendObservable } from 'mobx';
import { observer } from 'mobx-react';
const Test = () => {
extendObservable(this, {
button: false
});
const handleB1 = () => {
this.button = false;
}
const handleB2 = () => {
this.button = true;
}
const getButton2 = () => {
console.log('button2');
return (
<button type="button" onClick={handleB2}>Button 2</button>
);
};
const getButton1 = () => {
console.log('button1');
return …Run Code Online (Sandbox Code Playgroud) 我觉得我得到了大部分的mobx,但我想澄清一些事情.我有一个带有一些observable的商店,其核心是一个对象数组(typescript):
class ClientStore {
constructor() {
this.loadClients();
}
@observable private _clients: IClient[] = [];
@computed get clients() {
return this._clients;
}
@observable isFetching: boolean = false;
@observable sortField: 'title' | 'modified' = 'modified';
@observable sortDescending: boolean = true;
getClientByUrlName(urlName: string): IClient {
return this._clients.find(c => c.urlName === urlName);
}
etc...
Run Code Online (Sandbox Code Playgroud)
我的问题是最后一个函数 - getClientByUrlName.由于这是从一个可观察的发现,所以使用该函数的任何@observer反应组件都能正确重新渲染.对于类似的东西,这个惯用的mobx?感觉应该是计算值.我应该在要使用它的组件中是否为计算值?
//import singletone ClientStore
class ClientDetailsView extends React.Component<{params:{urlName:string}}, void> {
@computed get client() {
return ClientSotre.clients.find(c => c.urlName === this.props.params.urlName);
}
...rest of react component
Run Code Online (Sandbox Code Playgroud)
我正在寻找最好的做法和陷阱.任何帮助表示赞赏.
*编辑固定代码示例错误
当我从套接字获取新转储时,我需要替换我的observable对象中的数据:
class Store {
@observable data = { foo: 'bar' }
replaceFromDump(newData) {
this.data = newData
}
}
const store = new Store()
store.replaceFromDump({ foo: 'bar' })
// { foo: 'bar' } can be a huge amount of JSON
Run Code Online (Sandbox Code Playgroud)
但是,我注意到数据对象扩展时的性能命中,可能是因为即使某些属性/值相同,MobX也会在任何地方触发反应.
有一种"更聪明"的方式吗? - 我在想f.ex只替换对象的受影响部分会比替换整个observable更好吗?
我在这里做了一个小演示,解释了我的意思:https://jsfiddle.net/yqqxokme/.即使数据完全相同(预期),更换对象也会引起新的反应.但我确信有一种方法可以像在merge()函数中一样改变数据对象的受影响部分.
__PRE__
我尝试添加了decorators-legacy巴贝尔插件,并@babel/plugin-proposal-decorators与{ legacy: true }中.babelrc,但没有效果.
有人设法使MobX装饰器与CRA2一起工作吗?
我是 React 新手,当我阅读文档时,我发现有两种方法来实现 React 组件,基于函数和基于类。我知道在 React 16.8 之前不可能管理功能组件中的状态,但在那之后有了 React Hooks。
问题是,React Hooks 似乎有一个限制,它们只能在功能组件内部使用。以服务器-客户端为例,isAuthenticated当收到401时需要改变状态。
//client.js
import { useUserDispatch, signOut } from "auth";
export function request(url, args) {
var dispatch = useUserDispatch();
return fetch(url, args).then(response => {
if (response.status === 401) {
logout(dispatch);
}
}
);
//auth.js
import React from "react";
var UserStateContext = React.createContext();
var UserDispatchContext = React.createContext();
function userReducer(state, action) {
...
}
function UserProvider({ children }) {
var [state, dispatch] = React.useReducer(userReducer, {
isAuthenticated: false,
});
return …Run Code Online (Sandbox Code Playgroud) 我有一个商店:
class Store {
user!: User;
constructor() {
makeObservable(this, {
user: observable,
setUser: action
});
}
setUser = (user: User | undefined) => this.user = user;
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
Error: [MobX] Cannot apply 'observable' to 'Store@user': Field not found.
User是一个自定义对象,我应该以不同的方式对待他(可观察的明智的)?
提前致谢!
试图基本上完成这个https://github.com/elgerlambert/redux-localstorage,它适用于Redux但是为Mobx执行.并且最好想使用sessionStorage.有一个简单的方法来实现这个最小的样板吗?
我一直在使用MobX和Redux大约6个月.我发现在大多数应用程序中我更喜欢MobX的简单性.但是,我喜欢Redux的单店概念.我听到其他人评论他们用MobX创建了一个故事,我正试图确定最好的方法.目前,我创建了多个商店,然后将它们导入到单个商店中.
class UiStore {
@observable uiData;
constructor() {
this.uiData = {}
}
@action updateUI = (data) => {
this.uiData = {
data: data
};
}
}
let uiStore = new UiStore();
export default uiStore;
Run Code Online (Sandbox Code Playgroud)
class Store {
@observable currentUser;
constructor() {
this.auth = authStore;
this.ui = uiStore;
}
}
let store = new store();
export default store;
Run Code Online (Sandbox Code Playgroud)
在这里,我基本上创建了单独的商店,然后将它们合并到一个商店中,类似于redux减速器的工作原理.
还有其他/更好的方法吗?我想过可能会将一个商店导入到不同的文件中,并将一些方法和数据放在一个类上prototype.
mobx ×10
reactjs ×9
mobx-react ×4
javascript ×3
typescript ×2
babel ×1
decorator ×1
react-hooks ×1
react-native ×1
redux ×1