zoukankan      html  css  js  c++  java
  • Taro集成Redux快速上手的方法示例

    最近被一款来自京东凹凸实验室的多终端开发框架Taro吸粉了,官方对 Taro 的简介是使用React语法,一键生成多终端应用(包括小程序 / H5 / 快应用 / RN 等),而目前 Github 的 Star 也达到了非常可观的数量:4k+。对此,笔者也尝了把鲜,体验了下如何使用Taro写微信小程序。感觉还是十分灵活易用(一气呵成,都没遇到bug!),并且 Taro 还集成了 Redux,解决了小程序没有数据流框架的痛点。

    这里贴一个 Taro 的官方文档,有兴趣的同行们可以了解下~也可以和我交流~嘿嘿

    前言

    Redux是JavaScript 状态容器,提供可预测化的状态管理。一般来说,规模比较大的小程序,页面状态,数据缓存,需要管理的东西太多,这时候引入Redux可以方便的管理这些状态,同一数据,一次请求,应用全局共享。

    而Taro也非常友好地为开发者提供了移植的Redux。

    依赖

    为了更方便地使用Redux,Taro提供了与react-redux API 几乎一致的包 @tarojs/redux 来让开发人员获得更加良好的开发体验。

    开发前需要安装redux和@tarojs/redux以及一些需要用到的中间件

    $ yarn add redux @tarojs/redux redux-action redux-logger
    # 或者使用 npm
    $ npm install --save redux @tarojs/redux redux-action redux-logger
    

    示例

    下面通过实现一个Todolist快速上手Redux。

    1. 目录结构

    首先通过目录划分我们的store/reducers/actions。

    分别在文件夹里创建index.js,作为三个模块的主文件。reducers和actions里面的内容我们需要规划好功能之后再来处理。

    // store/index.js
     
    import { createStore, applyMiddleware } from 'redux'
     
    // 引入需要的中间件
    import thunkMiddleware from 'redux-thunk'
    import { createLogger } from 'redux-logger'
     
    // 引入根reducers
    import rootReducer from '../reducers'
     
    const middlewares = [
     thunkMiddleware,
     createLogger()
    ]
     
    // 创建store
    export default function configStore () {
     const store = createStore(rootReducer, applyMiddleware(...middlewares))
     return store
    }
    

    2. 编写Todos

    首先在app.js中引入一开始定义好的store,使用@tarojs/redux中提供的Provider组件将前面写好的store接入应用中,这样一来,被Provider包裹的页面都能共享到应用的store。

    import Taro, { Component } from '@tarojs/taro'
    import { Provider } from '@tarojs/redux'
     
    import configStore from './store'
    import Index from './pages/index'
     
    import './app.scss'
     
    const store = configStore()
     
    class App extends Component {
     ...
     render () {
      return (
       <Provider store={store}>
        <Index />
       </Provider> 
      )
     }
    }
    

    接下来就可以正式开始规划Todos应用的主要功能了。
    首先我们可以新建constants文件夹来定义一系列所需的action type常量。例如Todos我们可以先新增ADD和DELETE两个action type来区分新增和删除Todo指令。

    // src/constants/todos.js
     
    export const ADD = 'ADD'
    export const DELETE = 'DELETE'
    

    然后开始创建处理这两个指令的reducer。

    // src/reducers/index.js
     
    import { combineReducers } from 'redux'
    import { ADD, DELETE } from '../constants/todos'
     
    // 定义初始状态
    const INITIAL_STATE = {
     todos: [
      {id: 0, text: '第一条todo'}
     ]
    }
     
    function todos (state = INITIAL_STATE, action) {
     // 获取当前todos条数,用以id自增
     let todoNum = state.todos.length
      
     switch (action.type) { 
      // 根据指令处理todos
      case ADD:   
       return {
        ...state,
        todos: state.todos.concat({
         id: todoNum,
         text: action.data
        })
       }
      case DELETE:
       let newTodos = state.todos.filter(item => {
        return item.id !== action.id
       })
        
       return {
        ...state,
        todos: newTodos
       }
      default:
       return state
     }
    }
     
    export default combineReducers({
     todos
    })
    

    接着在action中定义函数对应的指令。

    // src/actions/index.js
     
    import { ADD, DELETE } from '../constants/todos'
     
    export const add = (data) => {
     return {
      data,
      type: ADD
     }
    }
     
    export const del = (id) => {
     return {
      id,
      type: DELETE
     }
    }
    

    完成上述三步之后,我们就可以在Todos应用的主页使用相应action修改并取得新的store数据了。来看一眼Todos的index.js。

    // src/pages/index/index.js
     
    import Taro, { Component } from '@tarojs/taro'
    import { View, Input, Text } from '@tarojs/components'
    import { connect } from '@tarojs/redux'
    import './index.scss'
     
    import { add, del } from '../../actions/index'
     
    class Index extends Component {
     config = {
      navigationBarTitleText: '首页'
     }
     
     constructor () {
      super ()
     
      this.state = {
       newTodo: ''
      }
     }
     
     saveNewTodo (e) {
      let { newTodo } = this.state
      if (!e.detail.value || e.detail.value === newTodo) return
     
      this.setState({
       newTodo: e.detail.value
      })
     }
     
     addTodo () {
      let { newTodo } = this.state
      let { add } = this.props
       
      if (!newTodo) return
     
      add(newTodo)
      this.setState({
       newTodo: ''
      })
     }
     
     delTodo (id) {
      let { del } = this.props
      del(id)
     }
     
     render () {
      // 获取未经处理的todos并展示
      let { newTodo } = this.state
      let { todos, add, del } = this.props 
     
      const todosJsx = todos.map(todo => {
       return (
        <View className='todos_item'><Text>{todo.text}</Text><View className='del' onClick={this.delTodo.bind(this, todo.id)}>-</View></View>
       )
      })
     
      return (
       <View className='index todos'>
        <View className='add_wrap'>
         <Input placeholder="填写新的todo" onBlur={this.saveNewTodo.bind(this)} value={newTodo} />
         <View className='add' onClick={this.addTodo.bind(this)}>+</View>
        </View>
        <View>{ todosJsx }</View> 
       </View>
      )
     }
    }
     
    export default connect (({ todos }) => ({
     todos: todos.todos
    }), (dispatch) => ({
     add (data) {
      dispatch(add(data))
     },
     del (id) {
      dispatch(del(id))
     }
    }))(Index)
    

    最后来看一眼实现的效果~~

    https://www.jb51.net/article/142376.htm

    https://www.cnblogs.com/crazycode2/p/12893905.html (taro 请求的封装)

  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/liliuyu/p/13923327.html
Copyright © 2011-2022 走看看