Giter Site home page Giter Site logo

swiftrx's Introduction

SwiftRX

Swift Package that brings Redux pattern into Swift!

Features

  • Lightweight
  • Code examples withing documentation of package types
  • Support for sub-states
  • Easy to use with SwiftUI
  • Fully tested

Instalation

Add dependency to Swift project: File -> Swift Packages -> Add Package Dependency

Search for: https://github.com/MatrixMZ/SwiftRX

Add to project.

Implementation

State

This defines model for your data that can be access inside the application. States can only be mutated by Reducers.

struct PostState: RXState {
    let posts: [Post] = []
}

Action

Defines a list of actions that can be used to mutate the State. It is good convention to keep Actions inside one group - struct for particular State. Actions can also have paylaod definition inside - it is constants.

# How to use with enums?
     enum PostAction: RXAction {
        // without payload
         case load
        // with payload
         case loadSuccess([Post])
         case loadFailure(String)
     }
     
# Or with structs:
    // without payload
    struct LoadPosts: RXAction { }
 
    // with payload
    struct LoadPostsSuccess: RXAction {
        let posts: [Post]
    }

Actions can be dispatched in Store.

store.dispatch(PostAction.AddOne(post: "New Post"))

Reducer

Reducer is a pure function, that takes and Action if confroms and State and returns mutated state.

// sub state reducer
// main state reducer
 let appReducer: RXReducer<AppState> = { state, action in
     var state = state
     
     state.posts = postsReducer(state.posts, action)
     
     return state
 }

// sub state reducer
 let postsReducer: RXReducer<PostsState> = { state, action in
     var state = state
     
     switch action as! PostAction {
         case .load:
             print("")
         case .loadSuccess(let posts):
             state.posts = posts
         case .loadFailure(let error):
             print(error)
    }
     
     return state
 }

Store

Store keeps the reactively changing data model in your application. Store can be subscribed to many places inside your application, very helpful can be EnvironmentObject for storing our Store. The data inside store can be only updated by dispatching an Action.Action can also provide additional data with its payload.

The key alements are State and its Reducer, they need to be injected inside store during the initialiation. The optional option is to add some Effects that will allow perform async request in your application and update data to your Store.

import SwiftRX

// Create State
 struct AppState: RXState {
     var posts = PostsState()
 }

// Create Reducer
 let appReducer: RXReducer<AppState> = { state, action in
     var state = state
     
     state.posts = postsReducer(state.posts, action)
     
     return state
 }

// Create Store instance
let store: RXStore<AppState> = RXStore(reducer: appReducer, state: AppState(), effects: [RXLogger()])


// Subscribing store

struct LoginView: View {
    // Store available in View
    @EnvironmentObject var store: RXStore<AppState>

        var body: some View {
            // Subscribing data from store
             Button("Total posts: \(store.state.posts.posts.count)") {
                // Dispatching an action
                store.dispatch(PostAction.load)

                // or with payload
                store.dispatch(PostAction.loadSuccess(Post(id: 10, title: "New Post")))

            }
        }
    }
}

AppView.swift and its sub views

struct AppView: View {
    @EnvironmentObject var store: RXStore<AppState>
}

Selector

It is optional but helps to create a shortcut path inside Views to access data from particular State in Store. Its a simple computed variable.

struct AppView: View {
    @EnvironmentObject var store: RXStore<AppState>

    // Define selector
    var productState: ProductState {
        return store.state.products
    }

    var body: some View {
        // Use selector to access data
        Text("Total products: \(productState.products.count)")
    }
}

Effects

Helfps to create a function that can be used to dispatch async RXAction. It can be usefull with making async API calls, or with creating middleware functions.

Every efect to be executed needs to be injected into Store initializer.

Effects are executed after the RXAction is dispatched. So you can make RXAction type check inside RXEffect's body to execute special code for partical effects.

func RXLogger() -> RXEffect<AppState> {
    return { state, action, dispatcher in
        print("[\(action.self)]")
    }
}

Extra

RXRequest<SuccessType, FailureType>

This enum supports getting and storing data catched from API requests.

struct PostsState: RXState {
    let posts: RXRequest<[Posts], String> = .initial
}

RXLogger

This DevTool - Effect prints out in terminal all names of dispatched Actions in Store to easly debug Store lifecycle.

var store = RXStore(reducer: appReducer, state: AppState(), effects: [
    RXLogger() // <- Inject logger here
])

Licence

Licence under the MIT Licence

swiftrx's People

Contributors

matrixmz avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.