zoukankan      html  css  js  c++  java
  • [Functional Programming + React] Provide a reasonable default value for mapStateToProps in case initial state is undefined

    For example we have a component, it needs to call 'react-redux' connect function.

    import { compose, curry, option, propPath } from '../js/helper'
    
    const FilterButton = ({ active, onClick }) => {
        const classes = classnames('filterButton', {
            'filterButton--active': active
        })
        return <Button className={classes} onClick={onClick} icon={faFilter} />
    }
    
    FilterButton.defaultProps = {
        active: true,
        onClick: Function.prototype
    }
    
    FilterButton.propTypes = {
        active: PropTypes.bool,
        group: PropTypes.string.isRequired,
        onClick: PropTypes.func
    }
    
    const mapStateToProps = (state, ownProps) => ({
        active: state.ui.filterGroups[ownProps.group]
    })
    
    export default connect(mapStateToProps)(FilterButton)

    For the hightlighted part, there can be many possible reason for it to go wrong. We can use Maybe to provide a reasonable default value.

    First, the inital State is:

    const data = {
        nextId: 4,
        todoFilter: 'SHOW_ALL',
        todos: [
           ...
        ],
        ui: {
            filterGroups: {
                status: false
            }
        }
    }

    If the highlighted part is undefined, we still want it works.

    import { chain, compose, curry, isBoolean, option, propPath, safe } from 'crocks'
    ...
    
    const activeGroup = curry(group =>
        compose(
            option(FilterButton.defaultProps.active),
    chain(safe(isBoolean)), propPath([
    'ui', 'filterGroups', group]) ) ) const mapStateToProps = (state, ownProps) => ({ active: activeGroup(ownProps.group, state) }) export default connect(mapStateToProps)(FilterButton)

    The reason to put a chain() there is because, if the initial state is not boolean but string value, we can do safe type check, to make sure, what we got is Boolean value in the end, it not a Boolean, then Option() will set it to false. 

    --Full code--

    import React from 'react'
    import PropTypes from 'prop-types'
    import { connect } from 'react-redux'
    import Button from './controls/Button'
    import classnames from 'classnames'
    import { faFilter } from '@fortawesome/free-solid-svg-icons'
    
    import { chain, compose, curry, isBoolean, option, propPath, safe } from 'crocks'
    
    const FilterButton = ({ active, onClick }) => {
        const classes = classnames('filterButton', {
            'filterButton--active': active
        })
        return <Button className={classes} onClick={onClick} icon={faFilter} />
    }
    
    FilterButton.defaultProps = {
        active: true,
        onClick: Function.prototype
    }
    
    FilterButton.propTypes = {
        active: PropTypes.bool,
        group: PropTypes.string.isRequired,
        onClick: PropTypes.func
    }
    
    const activeGroup = curry(group =>
        compose(
            option(FilterButton.defaultProps.active),
    chain(safe(isBoolean)), propPath([
    'ui', 'filterGroups', group]) ) ) const mapStateToProps = (state, ownProps) => ({ active: activeGroup(ownProps.group, state) }) export default connect(mapStateToProps)(FilterButton)
  • 相关阅读:
    Todo
    我的类
    Python socket编程之七:多窗口的应用
    iOS与PHP/Android AES128 ECB NoPadding加密
    JSONModel简便应用
    iOS开发系列--UITableView全面解析
    常用方法
    OC和C++混编
    数据层
    block
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10727119.html
Copyright © 2011-2022 走看看