Coder Social home page Coder Social logo

marko-redux's Introduction

marko-redux

Greenkeeper badge

Build Status Coverage Status

Simple redux bindings for marko, inspired by react-redux. You check out some example projects here and here.

Installation

npm i marko-redux

Why marko-redux?

Because I like marko and I like redux. redux is view layer agnostic, well supported, easy to learn, and easy to test. react-redux makes using redux easy, it removes the boilerplate and pain of having to pass down your store to all components to that care about it. This module aims to do the same for marko.

Why not marko-redux?

Depending on the scope of your application, you might not even need marko-redux. Apps with relatively simple state will do fine using only a root component's local state. The SAV Architecture described here will also manage state just fine for small apps that require a little more structure. This blog post should help explain things.

The API

This module exposes a <provider> component and a connect function for integrating with redux.

<provider>

The <provider> component is a wrapper component that should used at the root of an application. It is used to pass down the input redux store to all components defined using the connect function. A store can be passed to it via the store attribute.

Example Usage:

provider store=input.store
  // other components go here

Much like how redux recommends only having a single store in your application, you should only have a single <provider> (beware: using more than one can end up causing unexpected behavior).

connect(connectOptions)

connect is a higher order function for binding your store to your container components. A store can be passed down to connected components via the provider component (as explained above). The function accepts a single argument, an object containing information about how you want the store to interact with the container.

Here are the available fields you can specify for connectOptions:

  • mapStateToInput(state) - a function expecting the store's state to be passed in as the first argument. An object mapping how the state should be mapped to the component's input should be returned.
  • mapDispatchToInput(dispatch) - a function expecting the store's dispatch function to be passed in. An object mapping how action dispatch functions should be mapped to the component's input should be returned.
  • mapDispatchToComponent(dispatch) - an alternative to the above mapDispatchToInput function. This function instead exposes action dispatch functons to the component itself.
  • options - an additional configuration object that can contain the following fields
    • storeId - the id of the store to use (registered via the registerStore function defined above. If not specified, the default storeId will be used.

All of the above fields are optional, however it is recommended that mapInputToState and either mapDispatchToInput or mapDispatchToComponent are specified. This allows for redux to be used in full effect.

connect will return a function that can be used for binding the configuration to a component's definition.

That function accepts the component definition as the only argument.

It is recommended that connected components

Example usage:

const { connect } = require('marko-redux')

// pull in actions
const {
  increment,
  decrement,
  setCount
} = require('../../actions/counterActions')

// define marko component
class CounterContainer {
  onCreate (input) {
    // initialize container's state
    this.state = {
      count: input.count // derived from store's state
    }
  }

  // map input to container state
  // NOTE: this is needed to ensure that
  // the template defined by this container
  // is updated based on changes to the redux store
  onInput (input) {
    this.state.count = input.count // derived from store state
  }
}

// maps redux store state to the component's input
function mapStateToInput (state) {
  return {
    // component.input.count will equal redux.getState().count
    count: state.count
  }
}

// maps actions dispatch functions to
// methods that will be defined on the component
function mapDispatchToComponent (dispatch) {
  return {
    increment: () => dispatch(increment()),
    decrement: () => dispatch(decrement())
  }
}

// connects the marko-redux configuration to
// the component definition. The result is exported
// to be used by marko
module.exports = connect({
  mapStateToInput,
  mapDispatchToComponent
})(CounterContainer)

The container's template:

label -- count: ${state.count}

// clicking these buttons will call
// the dispatch functions exposed by
// `mapDispatchToComponent`
button onClick('increment') -- increment
button onClick('decrement') -- decrement

The root component using the container:

// provider will pass down store to counter-container
provider store=input.store
  counter-container

How it works

The <provider> attaches the input store to the async out object that is used by marko to render components for the first time. Components defined with the connect function will pull the store from out.

connect wraps the component's onCreate, onInput, and onDestroy methods, to allow for the redux store to be bound to the component (via the <provider> component). If mapDispatchToComponent is provided, then the functions exposed by it will be mapped to the component's definition.

When the component is created, it is automatically registered to the store via store.subscribe. As changes happen, either from new input being passed to the component or events coming from the store, the component's onInput will be invoked. The mapStateToInput and mapDispatchToInput functions will then be applied to the input.

Those values that are mapped to the input can be passed down to child components like normal.

When a dispatch function sends out an action and the store's state changes, the component will react to the change.

When the component is destroyed, it is subsequently unsubscribed from the redux store.

marko-redux's People

Contributors

ctdio avatar greenkeeper[bot] avatar greenkeeperio-bot avatar

Stargazers

Roman avatar Manuel Escudero avatar  avatar William Bewzenko avatar David avatar Francisco Yip avatar Sam Wenke avatar Austin Kelleher avatar

Watchers

 avatar

Forkers

franciscoyip

marko-redux's Issues

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on all branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please delete the greenkeeper/initial branch in this repository, and then remove and re-add this repository to the Greenkeeper App’s white list on Github. You'll find this list on your repo or organization’s settings page, under Installed GitHub Apps.

An in-range update of marko is breaking the build 🚨

The dependency marko was updated from 4.18.18 to 4.18.19.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

marko is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

Status Details
  • continuous-integration/travis-ci/push: The Travis CI build failed (Details).

Commits

The new version differs by 5 commits.

  • a5a735f 4.18.19
  • 1766b3b Update changelog
  • 828f13f Update htmljs-parser min version
  • 0b91cf9 Remove require.resolve from dom-data for improved rollup support
  • 05a91aa deprecate widget-id-prefix

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

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.