UNPKG

unstated-enhancers

Version:
207 lines (162 loc) 3.93 kB
# Unstated connect A redux like `connect` for `unstated` ## Installation ```bash npm install --save unstated-enhancers ``` ## Usage ```jsx // @flow import React, { Component } from 'react'; import { Container } from 'unstated'; import { connect } from 'unstated-enhancers'; type CounterState = { count: number }; class CounterContainer extends Container<CounterState> { state = { count: 0 }; name = 'Counter'; increment() { this.setState({ count: this.state.count + 1, __action: 'INCREMENT' }); } decrement() { this.setState({ count: this.state.count - 1, __action: 'DECREMENT' }); } } type MessageState = { message: string }; class MessageContainer extends Container<MessageState> { state = { message: 'Not defined' }; name = 'Messages'; change(message) { this.setState({ message: message, __action: 'MESSAGE_CHANGE' }); } random() { this.setState({ message: 'Random ' + Math.random(), __action: 'MESSAGE_RANDOM' }); } } class App extends Component { render() { // Get access to named containers const { counter, message } = this.props.containers; return ( <div> <header> <h1>App</h1> </header> <section> <div> <h4>Counter</h4> <button onClick={ () => counter.decrement() }>-</button> <button onClick={ () => counter.increment() }>+</button> <br /> <br /> <span>From counter state { counter.state.count }</span> <br /> <span>From mapped state to props { this.props.count }</span> <br /> <br /> </div> <div> <h4>Message</h4> <button onClick={ () => message.change('Updated') }>Update</button> <button onClick={ () => message.random() }>Random</button> <br /> <br /> <span>From message state { message.state.message }</span> <br /> <span>From mapped state to props { this.props.message }</span> <br /> <br /> </div> </section> </div> ); } } const containers = { counter: CounterContainer, message: MessageContainer }; const mapStateToProps = (containers) => { return { count: containers.counter.state.count, message: containers.message.state.message, } } const options = { mapCombinedContainers: true, concatCombinedContainerNames: true } export default connect(containers, mapStateToProps, options)(App); ``` ## API ### containers Type: `object` Object list of containers to be connected with the component ```js ... const containers = { counter: CounterContainer, message: MessageContainer }; ... ``` ### mapStateToProps Type: `Function` Function who maps containers state to component props ```js ... const mapStateToProps = (containers) => { return { count: containers.counter.state.count, message: containers.message.state.message, } } ... ``` ### options **mapCombinedContainers** Type: `boolean|Function` If a combined contaners is passed and this is setting to true it extracts the combined containers. You can provide your own `mapCombinedContainers` function if you want. ``` const mapCombinedContainers = (containers) => { return { list: containers.route.list, upsert: containers.route.upsert, info: containers.route.info } } ``` **concatCombinedContainerNames** Type: `boolean` <br> Default: `false` When multiple combined containers is passed to the connect function setting this option to true avoids containers name collision **loading** Type: `ReactNode` <br> Default: `null` Used the the `SubscribeGate` component to show up a loader when state is loaded from persistence. ```js const options = { loading: <p>Loading your app...</p> } ```