带复选框的Redux处理状态

时间:2019-06-10 19:08:48

标签: reactjs react-redux

与React合作已经有一段时间了,我最近一直在尝试了解Redux,目前我一直在处理多个复选框的问题上。很快,有一个用Create-React-app创建的待办事项列表,我在其中实现了3个复选框(默认选中),这些复选框应按优先级(高,正常,低)显示/隐藏任务。

我尝试通过将动作绑定到复选框来显示/隐藏具有不同优先级的任务来处理它。

复选框组件(Checkbox.js)


import React from 'react'
import PropTypes from 'prop-types'

const Checkbox = ({ checked, children, onChange }) => (
  <span>
    <input type = "checkbox" 
       onChange={onChange}
       defaultChecked={true}
       style={{
          marginLeft: '4px',
       }}
       className={'checkbox'}
    />
    {children}
  </span>   
)

Checkbox.propTypes = {
  checked: PropTypes.bool.isRequired,
  children: PropTypes.node.isRequired,
  onChange: PropTypes.func.isRequired
}

export default Checkbox

复选框容器(Filtercheckbox.js)


import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Checkbox from '../components/Checkbox'

const mapStateToProps = (state, ownProps) => ({
  checked: ownProps.filter === state.visibilityFilter
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  onChange: (e) =>  {
                    if(e.target.checked) dispatch(setVisibilityFilter(ownProps.filter[0]))
                    else dispatch(setVisibilityFilter(ownProps.filter[1]))
                }
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Checkbox)

父组件中的复选框


<FilterCheckbox filter={[VisibilityFilters.SHOW_HIGH, VisibilityFilters.HIDE_HIGH]}>
        High
</FilterCheckbox>
<FilterCheckbox filter={[VisibilityFilters.SHOW_NORMAL, VisibilityFilters.HIDE_NORMAL]}>
        Normal
</FilterCheckbox>
<FilterCheckbox filter={[VisibilityFilters.SHOW_LOW, VisibilityFilters.HIDE_LOW]}>
        Low
</FilterCheckbox>

Todolist容器


function getUnique(arr, comp) {
  const unique = arr
  .map(e => e[comp])
  .map((e, i, final) => final.indexOf(e) === i && i)
  .filter(e => arr[e]).map(e => arr[e]);
  return unique;
}

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case VisibilityFilters.SHOW_ALL:
      return todos
    case VisibilityFilters.SHOW_COMPLETED:
      return todos.filter(t => t.completed)
    case VisibilityFilters.SHOW_ACTIVE:
      return todos.filter(t => !t.completed)
    case VisibilityFilters.SHOW_HIGH:
      return getUnique(todos.concat(todos.filter(t => t.priority === 'High')), 'id')
    case VisibilityFilters.HIDE_HIGH:
        return todos.filter(t => t.priority !== 'High')
    case VisibilityFilters.SHOW_NORMAL:
        return getUnique(todos.concat(todos.filter(t => t.priority === 'Normal')), 'id')
    case VisibilityFilters.HIDE_NORMAL:
        return todos.filter(t => t.priority !== 'Normal')
    case VisibilityFilters.SHOW_LOW:
      return getUnique(todos.concat(todos.filter(t => t.priority === 'Low')), 'id')
    case VisibilityFilters.HIDE_LOW:
        return todos.filter(t => t.priority !== 'Low')
    default:
      throw new Error('Unknown filter: ' + filter)
  }
}

const mapStateToProps = state => ({
  todos: getVisibleTodos(state.todos, state.visibilityFilter)
})

const mapDispatchToProps = dispatch => ({
  toggleTodo: id => dispatch(toggleTodo(id)),
  choosePriority: (id, value) => dispatch(choosePriority(id, value))
})

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

Reducer发送新的可见性过滤器到状态


import { VisibilityFilters } from '../actions'

const visibilityFilter = (state = VisibilityFilters.SHOW_ALL, action) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
        return action.filter
    default:
      return state
  }
}

export default visibilityFilter

当选中一个复选框时,Todolist容器中的getVisibleTodos函数基本上只是组合两个数组(所有待办事项和具有特定优先级的待办事项),并返回一个唯一元素数组。

问题是当两个复选框都被取消选中时,在这种情况下,我们有不必要的待办事项(例如,如果我们在列表中具有“普通”和“高”优先级的待办事项,并且取消选中“普通”和“低”,则“普通”将重新出现)在列表上。)

0 个答案:

没有答案