zoukankan      html  css  js  c++  java
  • Taro集成Redux快速上手

    Taro集成Redux快速上手

    发布于 2018-06-20
    本文适合有一定React和Redux基础的用户阅读。

    前言的前言

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

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

    clipboard.png

    前言

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

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

    依赖

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

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

    ps:如果在h5要使用redux的话,还需要引入nerv-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

    2018-06-12-15-37-12

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

    // 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我们可以先新增ADDDELETE两个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)
    

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

    todos

  • 相关阅读:
    cmake
    docker
    rust
    linux
    FPGA
    visual studio
    win+R
    word文档的导出(用freemarker模板导出)(桃)
    iconfont的引入方法
    jquery 日期插件
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/13500268.html
Copyright © 2011-2022 走看看