search
HomeWeb Front-endJS TutorialReact-Native+Mobx implements mall APP

This time I will bring you React-Native Mobx to implement the mall APP. What are the precautions for implementing the mall APP with React-Native Mobx. The following is a practical case, let’s take a look.

I have been learning WeChat mini programs recently. During the learning process, I saw wxapp-mall I thought this WeChat applet project was very good, and the UI was quite small and fresh, so I cloned it to study it. While looking at the source code, I found that it was not complicated. I was really surprised to realize rich functions with not much code. So, I thought, would it be difficult to use react-native to make a small project like this? What's more, writing a set of code can run Android and iOS at the same time (the same goes for small programs...), how about writing one? Come and have fun? With this idea in mind, I directly Let’s write a react-native init project (๑•̀ㅂ•́)و✧

Technical framework and components

  • react "16.0.0"

  • react-native "0.51.0"

  • mobx: "3.4.1"

  • mobx-react: "4.3.5"

  • react-navigation: "1.0.0-beta.21"

  • react-native-scrollable-tab-view: "0.8.0"

  • react-native-easy-toast: "1.0.9"

  • react-native-loading-spinner-overlay: "0.5.2"

Why use Mobx?

Mobx is a scalable state management tool that is simpler than react-redux and faster to get started. In this small project, because there is no background service interface, all local fake data is used. In order to simulate the implementation Browse products =>Add to shopping cart=>Checkout=>Clear shopping cart=>Restore products to their original state In such a process, Mobx is used to manage all data and product status (whether it is selected, whether it is added to the shopping cart), so that all pages can share data and change the status of the product, and the data and products between pages can be shared. The status is updated synchronously. Specifically, how to use Mobx to implement this process, I will share my experience of using it and some pitfalls encountered below.

start

First react-native Init a project, and then use yarn or npm to install all dependencies and components. Because using Mobx will use the decorator in ES7, you need to install it babel-plugin-transform-decorators-legacy plug-in, and then add some content under the .babelrc file.

{ 
 "presets": ["react-native"], 
 "plugins": ["transform-decorators-legacy"]
}

Project Structure

|-- android 
|-- ios
|-- node_modules
|-- src
 |-- common // 公用组件
 |-- img // 静态图片
 |-- mobx // mobx store
 |-- newGoods.js // 首页新品数据
 |-- cartGoods.js // 购物车数据
 |-- categoryGoods.js // 分类页数据
 |-- store.js // store仓库,管理数据状态 
 |-- scene 
 |-- Cart // 购物车页面
 |-- Category // 分类页
 |-- Home // 首页
 |-- ItemDetail // 商品信息页
 |-- Mine // 我的页面 
 |-- Root.js // root.js主要内容是配置react-navigation(导航器)
|-- index.js // 主入口

In the Root.js file, regarding the configuration and usage of react-navigation, you can refer to the official documentation and this blog, which are written in great detail. I have found answers to questions about react-navigation in these two articles. The relevant react-navigation configuration, usage methods and project page layout and component writing are not going to be elaborated here because they are relatively simple. They are more about discussing some logic and methods of Mobx implementation functions. , The components under the screen folder are all commented (°ー°〃)

Let’s mainly talk about Mobx

1. Data storage and retrieval

These are simulated and implemented using fake data. At the very beginning, write the data structure of the fake data, for example:

"data":
 [{ 
 "name": '那么大西瓜',
 "price": '2.0', 
 "image": require('../img/a11.png'), 
 "count": 0, 
 "isSelected": true
 },...]

store.js in the Mobx folder, here it mainly stores and manages the data of all products used by the app, and moves the logic and state from the component to an independent, testable unit. This unit is on each page. You can use it

import { observable, computed, action } from 'mobx'
import cartGoods from './cartGoods'
import newGoods from './newGoods'import categoryGoods from './catetgoryGoods'
/** 
* 根store 
* @class RootStore 
* CartStore 为购物车页面的数据 
* NewGoodsStore 为首页的数据 
* categoryGoodsStore 为分类页的数据 
*/
class RootStore { 
 constructor() { 
 this.CartStore = new CartStore(cartGoods,this) 
 this.NewGoodsStore = new NewGoodsStore(newGoods,this) 
 this.categoryGoodsStore = new categoryGoodsStore(categoryGoods,this) 
}}
Class CartStore{
 @observable allDatas = {} 
 constructor(data,rootStore) { 
 this.allDatas = data 
 this.rootStore = rootStore 
 }
}
Class NewGoodsStore{
 ...跟上面一样
}
Class categoryGoodsStore{
 ...跟上面一样
}
// 返回RootStore实例 
export default new RootStore()

RootStore is used here to instantiate all stores (shopping cart, homepage, and category pages have their own stores),

In this way, stores can be managed and operated through RootStore, allowing them to communicate with each other and share references.

Secondly, the @observable method of Mobx is used to store data, which turns the data into an observer. When the user operates the view and causes the data to change, the view can be automatically updated with the @observer provided by react-mobx, which is very convenient.

In addition, in order to inject Mobx's Rootstore into react-native components, it must be implemented through the Provider provided by mobx-react. Under Root.js, I wrote this:

// 全局注册并注入mobx的Rootstore实例,首页新品,分类页,商品详情页,购物车页面都要用到store
import {Provider} from 'mobx-react'
// 获取store实例
import store from './mobx/store' 
const Navigation = () => { 
 return ( 
 <provider> 
 <navigator></navigator> 
 </provider> 
)}

After injecting the Rootstore instance into the component tree, can it be obtained directly by using this.props.rootStore in the component?

‘'不是的”,我们还需要在要用到Rootstore的组件里,要加点小玩意,在 HomeScreen.js (首页)中这么写:

import { inject, observer } from 'mobx-react'
@inject('rootStore') // 缓存rootStore,也就是在Root.js注入的
@observerexport default class HomeScreen extends Component {
 ......
}

加上了 @inject('rootStore') ,我们就可以愉快地使用 this.props.rootStore 来拿到我们想要的数据啦^_^ ,同样,在商品信息,分类页,购物车页面js下,也需要使用 @inject('rootStore') 来实现数据的获取,然后再一步步地把数据传到它们的子组件中。

2. 加入购物车的实现

在首页和分类页中,都可以点击跳转到商品信息页,然后再加入到购物车里

React-Native+Mobx implements mall APP 

实现方法 :

在itemDetail.js下,也就是商品信息页面下,加入购物车的逻辑是这样子的:

addCart(value) {
 if(this.state.num == 0) { 
 this.refs.toast.show('添加数量不能为0哦~')
 return; 
} 
// 加入购物车页面的列表上 
// 点一次,购物车数据同步刷新 
this.updateCartScreen(value)
this.refs.toast.show('添加成功^_^请前往购物车页面查看')
}
// 同步更新购物车页面的数据
updateCartScreen (value) { 
 let name = this.props.navigation.state.params.value.name;
 // 判断购物车页面是否存在同样名字的物品 
 let index;
 if(this.props.rootStore.CartStore)
 index = this.props.rootStore.CartStore.allDatas.data.findIndex(e => (e.name === name))
 // 不存在
 if(index == -1) {
 this.props.rootStore.CartStore.allDatas.data.push(value) 
 // 加入CartStore里
 // 并让购物车icon更新
 let length = this.props.rootStore.CartStore.allDatas.data.length 
 this.props.rootStore.CartStore.allDatas.data[length - 1].count += this.state.num}
 else { 
 // 增加对应name的count
 this.props.rootStore.CartStore.allDatas.data[index].count += this.state.num 
 }}

简单的说,先获取水果的名称name,然后再去判断Mobx的CartStore里面是否存在同样的名称的水果,如果有就增加对应name的数量count,如果没有,就往CartStore中增加数据,切换到购物车页面时,视图会同步刷新,看到已加入购物车的水果。

3.改变商品状态同步更新视图

当用户在购物车页面操作商品状态时,数据改变时,视图会跟着同步刷新。

例如,商品的增加数量,减少数据,选中状态,商品全选和商品删除,总价格都会随着商品的数量变化而变化。

 

图又来了~~

实现上面的功能,主要用到了Mobx提供的action方法,action是用来修改状态的,也就是用action来修改商品的各种状态(数量,选中状态...),这些action,我是写在 store.js 的 CartStore类 中的,下面贴出代码

// 购物车store
class CartStore {
 @observable allDatas = {}
 constructor(data,rootStore) { 
 this.allDatas = data
 this.rootStore = rootStore
}
 //加
 @action
 add(money) { 
 this.allDatas.totalMoney += money 
}
 // 减
 @action
 reduce(money) { 
 this.allDatas.totalMoney -= money 
}
 // checkbox true 
 @action
 checkTrue(money) {
 this.allDatas.totalMoney += money
 } 
 // checkbox false
 @action
 checkFalse(money) {
 if(this.allDatas.totalMoney  {
 this.allDatas.totalMoney += e.count * e.price})}
 else { 
 this.allDatas.totalMoney = 0 
}}
 // check全选 
 @action 
 check() { 
 // 所有checkbox为true时全选才为true 
 let allTrue = this.allDatas.data.every(v => ( v.isSelected === true ))
 if(allTrue) { 
 this.allDatas.isAllSelected = true 
 }else { 
 this.allDatas.isAllSelected = false 
}}
 // 删 
 @action
 delect(name) { 
 this.allDatas.data = this.allDatas.data.filter (e => (e.name !== name ))
}
 // 总价格
 @computed get totalMoney() { 
 let money = 0;
 let arr = this.allDatas.data.filter(e => (e.isSelected === true))
 arr.forEach(e=> (money += e.price * e.count))
 return money
}}

所有修改商品状态的逻辑都在上面代码里面,其中,totalMoney是用了Mobx的@computed方法,totalMoney是依赖于CartStore的data数据,也就是商品数据,但data的值发生改变时,它会重新计算返回。如果了解vue的话,这个就相当于vue的计算属性。

4.结算商品

商品结算和清空购物车的逻辑都写在 CartCheckOut.js 里面,实现过程很简单,贴上代码吧:

// 付款
 pay() { 
 Alert.alert('您好',`总计:¥ ${this.props.mobx.CartStore.totalMoney}`, 
 {text: '确认支付', onPress: () => this.clear()},
 {text: '下次再买', onPress: () => null}],{ cancelable: false })}
 // 清空购物车 
 clear() { 
 this.setState({visible: !this.state.visible})
 setTimeout(()=>{ 
 this.setState({ loadText: '支付成功!欢迎下次光临!' }) 
 setTimeout(()=> { this.setState({ visible: false },
 ()=>{ this.props.mobx.CartStore.allDatas.data = []
 // 把所有商品count都变为0 
 this.props.mobx.NewGoodsStore.allDatas.data.forEach(e=> e.count = 0)
 this.props.mobx.categoryGoodsStore.allDatas.data.forEach( e => { 
 e.detail.forEach(value => { value.count = 0 }) 
 })
 })},1500)},2000)}

这里主要用了setTimeout和一些方法来模拟实现 支付中 => 支付完成 => 清空购物车 => 还原商品状态。

好了,这个流程就搞定了,哈哈。

5.遇到的小坑

1.我写了一个数组的乱序方法,里面有用到 Array.isArray() 这个方法来判断是否为数组,但是,我用这个乱序函数时,想用来搞乱store里面的数组时,发现一直没有执行,觉得很奇怪。然后我直接用 Array.isArray() 这个方法来判断store里面的数组,返回的一直都是false。。。于是我就懵了。。。后来,我去看了Mobx官方文档,终于找到了答案。原来,store里面存放的数组,并不是真正的数组,而是 obverableArray ,如果要让 Array.isArray() 判断为true,就要在取到store的数组时,加个. slice() 方法,或者 Array.from() 都可以。

2.同样,也是obverableArray的问题。在购物车页面时,我用了FlatList来渲染购物车的item,起初,当我增加商品到购物车,发现购物车页面并没有刷新。有了上面的踩坑经验,我认为是obverableArray引起的,因为FlatList的data接收的是real Array,于是,我用这样的方法:

@computed get dataSource() { 
 return this.props.rootStore.CartStore.allDatas.data.slice();
}
...
<flatlist></flatlist>

于是,购物车视图就可以自动地刷新了,在官方文档上也有写到。

3.还有一个就是自己粗心造成的。我写完这个项目后,和朋友出去玩时,顺便发给朋友看看,他在删除商品时发现,从上往下删删不了,从下往上删就可以。后来我用模拟器测试也是如此,于是就去看看删除商品的逻辑,发现没有问题,再去看store的数据,发现也是可以同步更新的,只是视图没有更新,很神奇,于是我又在FlatList去找原因,终于,原因找到了,主要是在keyExtractor里面,用index是不可以的,要用name来作为key,因为我删除商品方法其实是根据name来删的,而不是index,所以用index来作为FlatList的Item的key时是会出现bug的。

_keyExtractor = (item,index)=> { 
 // 千万别用index,不然在删购物车数据时,如果从第一个item开始删会产生节点渲染错乱的bug 
 return item.name
}

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Angular实现可添加删除与计算总金额效果插件

AngularJS实现猜数字小游戏

The above is the detailed content of React-Native+Mobx implements mall APP. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
如何利用PHP实现商城的积分商城功能如何利用PHP实现商城的积分商城功能May 26, 2023 am 08:24 AM

现如今,随着电商行业的不断发展,积分商城功能已经越来越受到人们的关注和喜爱。顾客可以通过积分兑换商城中的商品,不仅为商家积攒人气,也使得顾客消费更具有吸引力。在这方面,PHP作为一种流行的编程语言,其优秀的性能和丰富的库使得开发者可以轻松地实现这一功能。在开发积分商城时,我们需要分为三个模块:用户模块、商品模块、订单模块。一、用户模块1.用户登录/注册在实现

如何使用PHP实现商城的品牌搜索功能如何使用PHP实现商城的品牌搜索功能May 22, 2023 am 08:32 AM

近年来,随着互联网的快速发展,电商行业的崛起已成为现代商业中的一股主流趋势。而其中最具代表性的商业类型就是“购物商城”,以淘宝、京东等为代表,这些平台的业务涉及人员、库存、订单、物流等多种方面。其中,搜索功能对于购物商城的生存发展至关重要。在购物商城中,品牌搜索是用户常用的搜索方式之一。本文将以PHP为主,介绍如何使用PHP实现商城的品牌搜索功能。一、如何建

如何利用PHP实现商城的批量操作功能如何利用PHP实现商城的批量操作功能May 21, 2023 pm 05:31 PM

随着电子商务的迅速发展和市场需求的日益增长,现今的商城平台已经从原本简单的商品展示转化为功能复杂、操作繁琐的综合商业平台。在这种情况下,如何快速高效地完成商城管理工作就成为了消费者、商家和管理员的共同目标。而在商城管理中,批量操作功能可以帮助管理员快速完成复杂且繁琐的操作任务。如何使用PHP实现批量操作功能,让商城管理员更加高效地完成管理任务,成为了当前商城

如何利用PHP实现商城的礼品卡系统如何利用PHP实现商城的礼品卡系统May 26, 2023 am 08:01 AM

随着互联网的不断发展,越来越多的消费者开始通过电子商城进行购物,而在电子商城中,礼品卡成为了一种非常受欢迎的赠送方式。那么,如何利用PHP实现商城的礼品卡系统呢?本文将为大家介绍相关实现方法。一、礼品卡系统的设计1、礼品卡的生成首先,我们需要设计礼品卡的生成方法。通常,每一张礼品卡需要一个唯一的编号和一定的面值。在PHP中,可以使用随机数生成一个唯一的编号。

如何利用PHP开发商城的场景化营销功能如何利用PHP开发商城的场景化营销功能May 27, 2023 am 09:10 AM

随着电商行业的发展,越来越多的企业开始选择搭建自己的网上商城。在市场竞争日益激烈的情况下,商城的营销功能显得尤为重要。本文将介绍如何利用PHP开发商城的场景化营销功能来提升用户的购买体验和增加销售额。一、了解市场在开发商城的场景化营销功能之前,我们首先需要了解市场需求。我们可以借助百度指数、Google趋势等工具来查看用户的搜索词汇和搜索量,这样有利于我们更

如何利用PHP实现商城的闪购功能如何利用PHP实现商城的闪购功能May 22, 2023 pm 08:10 PM

作为一款常用的Web编程语言,PHP被广泛应用于电商平台的开发中。其中,闪购功能成为了电商平台的重点之一,因此掌握如何利用PHP实现商城的闪购功能对电商平台的开发者来说非常必要。本文将介绍如何使用PHP实现商城的闪购功能。一、闪购的概念闪购是指电商平台提供的一种限时抢购商品的功能。在闪购期间,消费者可以以低于原价的价格购买商品。一般情况下,闪购的持续时间较短

如何利用PHP开发商城实现订单退款申请流程功能如何利用PHP开发商城实现订单退款申请流程功能Jun 29, 2023 am 09:17 AM

如何利用PHP开发商城实现订单退款申请流程功能随着电子商务的不断发展,线上购物越来越成为人们的主要购物方式。然而,在线购物也存在一些风险,比如商品与描述不符、商品质量问题等,这时消费者就会选择申请退款。因此,一个完善的订单退款申请流程功能是一个商城系统不可或缺的一部分。本文将介绍如何利用PHP开发商城实现订单退款申请流程功能。一、数据库设计首先,我们需要设计

PHP商城中的自动化运营工具介绍PHP商城中的自动化运营工具介绍May 22, 2023 pm 07:01 PM

随着电商行业的飞速发展,越来越多的商家选择将自己的业务转移到了在线平台上。其中,商城网站是较为常见的一种电商模式,而PHP商城则是国内比较流行的一种建站工具之一。随着用户量的不断增长,商家在处理海量用户数据和订单信息时难免会面临一些管理上的问题。针对这些问题,PHP商城中也配备了一些自动化运营工具,能够帮助商家轻松管理店铺,提高效率,下面着重介绍几种常用的自

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft