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)
  • 相关阅读:
    Algorithm --> KMP算法
    Algorithm --> 快速排序
    Algorithm --> 阶乘和因子
    Algorithm --> Dijkstra和Floyd最短路径算法
    Algorithm --> 二分图最大匹配
    Algorithm --> 邮票连续组合问题
    Algorithm --> 字母重排
    Algorithm --> 6174问题
    Algorithm --> 字符串中最长不重合子串长度
    Algorithm --> DFS和BFS
  • 原文地址:https://www.cnblogs.com/Answer1215/p/10727119.html
Copyright © 2011-2022 走看看