react 使用 mobx
by Miles Till
由Miles Till
如何使用React和MobX状态树构建基于状态的路由器 (How to build a state-based router using React and MobX State Tree)
Introducing mobx-state-tree-router
If you want to skip ahead to the finished example you can check it out at mobx-state-tree-router-demo.
如果您想跳至完成的示例,可以在mobx-state-tree-router-demo上进行检查 。
I wrote a library that makes it easy to configure state-based routing in MobX State Tree powered React apps, and I want to share it with you. To do this I will demonstrate how to build a very simple Todo app.
我写了一个库,使在MobX状态树驱动的React应用程序中配置基于状态的路由变得容易,我想与您共享它。 为此,我将演示如何构建一个非常简单的Todo应用程序。
Michel Weststrate, the creator of MobX, wrote a great article titled How to decouple state and UI (a.k.a. you don’t need componentWillMount). I recommend reading it to understand the philosophy that inspired me to write mobx-state-tree-router. The key idea is that the application UI should be a function of the state.
MobX的创建者Michel Weststrate写了一篇很棒的文章,标题为《 如何使状态与UI分离》(又称您不需要componentWillMount) 。 我建议阅读它以了解启发我编写mobx-state-tree-router的哲学。 关键思想是应用程序UI应该是状态的函数。
“This approach has better decoupling of state and UI. This has a few advantages:
“这种方法可以更好地将状态与UI分离。 这有一些优点:
1. The complete application flow can be tested without ever needing to instantiate a component.
1.无需实例化组件即可测试完整的应用程序流程。
2. More components can be dumb; they don’t have to fetch data or process routing.
2.可以使更多组件变得笨拙; 他们不必获取数据或处理路由。
3. Our stores become more like a state machine, making it easy to follow the transitions of our application.”
3.我们的商店变得更像一台状态机,可以轻松地跟踪我们的应用程序的过渡。”
- Michel Weststrate
-米歇尔·韦斯特斯特
先决条件 (Prerequisites)
These will need to be installed to follow this tutorial:
必须安装这些程序才能遵循本教程:
Node.js — used for running the dev server
Node.js-用于运行开发服务器
Yarn — used for package management
纱线 -用于包装管理
Note: NPM can be used instead of Yarn but some commands may be different.
注意:可以使用NPM代替Yarn,但是某些命令可能有所不同。
创建一个基本的React应用 (Create a basic React app)
使用create-react-app快速入门 (Use create-react-app to get started quickly)
If you haven’t used it before, the easiest way to get started with a React app is to use a scaffolding tool by the developers of React called Create React App. This tool configures Webpack and Babel for you with the most common requirements met.
如果您以前从未使用过它,那么最开始使用React应用程序的最简单方法是使用React开发人员的脚手架工具,称为创建React App 。 该工具为您配置Webpack和Babel ,使其满足最常见的要求。
In your terminal run the following commands:
在您的终端中运行以下命令:
npx create-react-app state-router-democd state-router-demoyarn start
You will now have a fully functioning basic React app to play with.
现在您将拥有一个功能齐全的基本React应用程序。
删除此示例不需要的create-react-app内容 (Remove create-react-app stuff not needed for this example)
For the purposes of this tutorial we don’t need a lot of the stuff that create-react-app generates so go ahead and delete:
就本教程而言,我们不需要大量create-react-app生成的东西,因此请继续删除:
src/App.csssrc/App.test.jssrc/index.csssrc/logo.svgsrc/serviceWorker.js
Note: Feel free to keep the css files and add your own styling.
注意:随时保留css文件并添加自己的样式。
To keep things organised, create a components
directory in our src
and move src/App.js
to src/components/App.js
.
为了使事情井井有条,请在src
创建一个components
目录,然后将src/App.js
移至src/components/App.js
Now update the following files to remove references to the files we deleted:
现在更新以下文件,以删除对我们删除的文件的引用:
src/components/App.js
src / components / App.js
src/index.js
src / index.js
If you still have the app running you will notice your browser has updated to show you the following:
如果您仍在运行该应用程序,则会注意到您的浏览器已更新,可以显示以下内容:
创建一个主页组件 (Create a Home page component)
In the components
directory, create a file for our Home page component:
在components
目录中,为我们的主页组件创建一个文件:
src/components/Home.js
src / components / Home.js
Update the App component to render our new Home page component:
更新App组件以呈现我们的新Homepage组件:
src/components/App.js
src / components / App.js
添加MobX状态树模型 (Add MobX State Tree models)
安装MobX和MobX状态树 (Install MobX and MobX State Tree)
MobX is a library for state management, and it works great with React as our renderer. MobX State Tree is a tree shaped state container built on top of MobX.
MobX是用于状态管理的库,与React作为我们的渲染器一起使用时效果很好。 MobX状态树是建立在MobX之上的树状状态容器。
In your terminal run:
在您的终端运行中:
yarn add mobx mobx-react mobx-state-tree
Like our we did for our components, create a models
directory to keep our MobX State Tree models organised.
就像我们对组件所做的一样,创建一个models
目录以保持我们的MobX状态树模型井井有条。
创建一个RootStore模型 (Create a RootStore model)
In our state tree we’ll have a RootStore
which holds our data stores (in this case a TodoStore
) and our RouterStore
, but we’ll get to that later.
在我们的状态树中,我们将有一个RootStore
来保存我们的数据存储(在本例中为TodoStore
)和我们的RouterStore
,但是我们稍后RouterStore
。
src/models/RootStore.js
src / models / RootStore.js
创建TodoStore和Todo模型 (Create TodoStore and Todo models)
Our TodoStore
contains Todo
objects which are able to be created, removed, and updated. We also need to be able to find a Todo
object by its id
.
我们的TodoStore
包含可以创建,删除和更新的Todo
对象。 我们还需要能够通过其id
查找Todo
对象。
src/models/TodoStore.js
src / models / TodoStore.js
初始化RootStore (Initialize the RootStore)
When our app loads, we want to initialize the RootStore
with a known state. For this trivial example we won’t be concerned about persisting our data to storage in any way. We then want to make sure the RootStore
is available to be injected into our components, so we use the MobX React component Provider
to do this.
应用加载时,我们想用已知状态初始化RootStore
。 对于这个简单的示例,我们将不关心以任何方式将数据持久存储到存储中。 然后,我们要确保可以将RootStore
注入到我们的组件中,因此我们使用MobX React组件Provider
来执行此操作。
src/index.js
src / index.js
创建一个TodoList页面组件 (Create a TodoList page component)
Now that we have a RootStore
for our state tree, we need some components to view and change the data.
现在,我们为状态树提供了一个RootStore
,我们需要一些组件来查看和更改数据。
src/components/TodoList.js
src / components / TodoList.js
Update the App
component to display our new TodoList
component.
更新App
组件以显示我们的新TodoList
组件。
src/components/App.js
src / components / App.js
At this point the app should have a list of Todo
objects which you can add to and remove from.
此时,该应用程序应具有您可以添加和删除的Todo
对象的列表。
创建一个Todo页面组件 (Create a Todo page component)
Now we want to create a new component to display and edit a Todo
object. Note that we are using inject
to make the RootStore
available in the component’s props.
现在,我们要创建一个新组件以显示和编辑Todo
对象。 请注意,我们正在使用inject
使RootStore
在组件的props中可用。
src/components/Todo.js
src / components / Todo.js
Update the App
component to display our new Todo
component.
更新App
组件以显示我们的新Todo
组件。
Now our updated app allows us to edit the data of the Todo
whose id we pass to the Todo page component in <Todo todoId={0}
/>.
现在,我们更新的应用程序允许我们编辑Todo
的数据,该ID的ID传递到<Todo todoId={0}
/>中的Todo页面组件。
添加基于状态的路由 (Add state-based routing)
At this point we should have a React app with our data stored in a MobX State Tree container. The data container is then being injected into the components that need access to the data. Now we want to connect together our page components in our app. A common approach would be to use a component based router such as React Router. Often the components become cluttered with route definitions and mount event handlers. This doesn’t suit our state-first philosophy.
此时,我们应该有一个React应用,其数据存储在MobX状态树容器中。 然后将数据容器注入需要访问数据的组件中。 现在,我们要将应用程序中的页面组件连接在一起。 一种常见的方法是使用基于组件的路由器,例如React Router 。 通常,组件会因路由定义和安装事件处理程序而变得混乱不堪。 这不符合我们的国家优先理念。
I will now show you how to add mobx-state-tree-router to your app.
现在,我将向您展示如何向您的应用添加mobx-state-tree-router。
安装mobx-state-tree-router (Install mobx-state-tree-router)
In your terminal run:
在您的终端运行中:
yarn add mobx-state-tree-router
将路由器添加到RootStore (Add the router to the RootStore)
src/models/RootStore.js
src / models / RootStore.js
创建视图 (Create views)
The router needs to be configured with a map of view models which define the route paths to match against and the page components to display. Hooks into the page change cycle can be defined on a view to perform data fetching, route change cancelling, redirection, and other tasks. These hooks can be synchronous or asynchronous.
路由器需要配置一个视图模型图,以定义要匹配的路由路径以及要显示的页面组件。 可以在视图上定义页面更改周期的挂钩,以执行数据获取,路由更改取消,重定向和其他任务。 这些挂钩可以是同步的或异步的。
These hooks are:
这些挂钩是:
beforeExit(self, params)
beforeExit(self, params)
beforeEnter(self, params)
beforeEnter(self, params)
onExit(self, params)
onExit(self, params)
onEnter(self, params)
onEnter(self, params)
If either of the before hooks return false
the route change will be cancelled.
如果任何一个前钩返回false
则路由更改将被取消。
Create a views
file:
创建一个views
文件:
src/views.js
src / views.js
启动我们的应用程序时初始化路由器 (Initialize the router when our app starts)
The router can be started by calling startRouter(router)
. This function connects the router to the browser’s history and configures the routing based on router’s views.
可以通过调用startRouter(router)
来启动startRouter(router)
。 此功能将路由器连接到浏览器的历史记录,并根据路由器的视图配置路由。
src/index.js
src / index.js
渲染StateRouter (Render the StateRouter)
Update the App
component to include the StateRouter
component, which renders the appropriate component for the router’s current view.
更新App
组件以包括StateRouter
组件,该组件将为路由器的当前视图呈现适当的组件。
src/components/App.js
src / components / App.js
Now our app will respond to changes in the url path, for example /todos
will show our TodoList
component and /todos/0
will show our Todo
component as configured in views.js
.
现在,我们的应用程序将响应url路径中的更改,例如/todos
将显示我们的TodoList
组件, /todos/0
将显示我们的Todo
组件,它们在views.js
配置。
添加导航链接 (Add navigation links)
Currently our app doesn’t have any way to navigate around other than changing the url directly. This doesn’t work particularly well in this simple example as the data in our RootStore
will get reset to the initial state as defined in index.js
every time the page loads.
目前,除了直接更改网址外,我们的应用程序没有其他导航方式。 在这个简单的示例中,这并不是特别有效,因为每次页面加载时, RootStore
的数据都会重置为index.js
定义的初始状态。
There are 2 other ways to change the route using mobx-state-tree-router:
还有另外两种使用mobx-state-tree-router更改路由的方法:
Link
componentsLink
组件Calling
router.setView(view, params)
directly直接调用
router.setView(view, params)
I recommend using Link
components where possible, but in some cases (like redirects) setting the view directly may be unavoidable. Let’s update our App
and TodoList
components to add some navigation links using both methods:
我建议尽可能使用Link
组件,但是在某些情况下(例如重定向),直接设置视图可能是不可避免的。 让我们更新App
和TodoList
组件,以使用这两种方法添加一些导航链接:
src/components/App.js
src / components / App.js
src/components/TodoList.js
src / components / TodoList.js
You will now be able to add a Todo
item on the todos
view, then click the open button to go the todo
view for the new item:
现在,您就可以添加一个Todo
的项目todos
视图,然后单击打开按钮去todo
视图新项目:
结论 (Conclusion)
I created mobx-state-tree-router because I found that there was a gap in the landscape for a state-based routing library to use with MobX State Tree. I have found it to be useful for me, so I hope it can also be useful to the wider community.
我创建了mobx-state-tree-router,是因为发现在景观中存在一个空白状态,无法将基于状态的路由库与MobX状态树一起使用。 我发现它对我有用,因此我希望它对更广泛的社区也有用。
If you haven’t already please read Michel Weststrate’s article for some background on state-based routing.
如果您还没有,请阅读Michel Weststrate的文章,以获取有关基于状态的路由的一些背景知识。
If you have any issues to raise or contributions to make, please head over to mobx-state-tree-router on Github.
如果您有任何问题需要筹集或作出贡献,请前往Github上的mobx-state-tree-router 。
react 使用 mobx