加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Redux Todo 列表示例教程

发布时间:2023-04-06 14:01:45 所属栏目:教程 来源:
导读:这是我们在基础教程里开发的迷你型的任务管理应用的完整源码。

这个代码也在我们的 example 仓库可以找到。 当然也可以在浏览器通过 CodeSandbox 运行.

入口文件
index.js
import React from 'react&#39
这是我们在基础教程里开发的迷你型的任务管理应用的完整源码。

这个代码也在我们的 example 仓库可以找到。 当然也可以在浏览器通过 CodeSandbox 运行.

入口文件
index.js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rootReducer from './reducers'
import App from './components/App'
 
const store = createStore(rootReducer)
 
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
创建 Action
actions/index.js
let nextTodoId = 0
export const addTodo = text => ({
  type: 'ADD_Todo',
  id: nextTodoId++,
  text
})
 
export const setVisibilityFilter = filter => ({
  type: 'SET_VISIBILITY_FILTER',
  filter
})
 
export const toggletodo = id => ({
  type: 'TOGGLE_Todo',
  id
})
 
export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}
Reducers
reducers/todos.js
const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_Todo':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_Todo':
      return state.map(todo =>
        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
      )
    default:
      return state
  }
}
 
export default todos
reducers/visibilityFilter.js
const visibilityFilter = (state = 'SHOW_ALL', action) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}
 
export default visibilityFilter
reducers/index.js
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
 
export default combineReducers({
  todos,
  visibilityFilter
})
展示组件
components/Todo.js
import React from 'react'
import PropTypes from 'prop-types'
 
const Todo = ({ onClick, completed, text }) => (
  <li
    onClick={onClick}
    style={{
      textdecoration: completed ? 'line-through' : 'none'
    }}
  >
    {text}
  </li>
)
 
Todo.propTypes = {
  onClick: PropTypes.func.isrequired,
  completed: PropTypes.bool.isrequired,
  text: PropTypes.string.isrequired
}
 
export default Todo
components/TodoList.js
import React from 'react'
import PropTypes from 'prop-types'
import Todo from './Todo'
 
const TodoList = ({ todos, toggletodo }) => (
  <ul>
    {todos.map(todo => (
      <Todo key={todo.id} {...todo} onClick={() => toggletodo(todo.id)} />
    ))}
  </ul>
)
 
TodoList.propTypes = {
  todos: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number.isrequired,
      completed: PropTypes.bool.isrequired,
      text: PropTypes.string.isrequired
    }).isrequired
  ).isrequired,
  toggletodo: PropTypes.func.isrequired
}
 
export default TodoList
components/Link.js
import React from 'react'
import PropTypes from 'prop-types'
 
const Link = ({ active, children, onClick }) => (
  <button
    onClick={onClick}
    disabled={active}
    style={{
      marginLeft: '4px'
    }}
  >
    {children}
  </button>
)
 
Link.propTypes = {
  active: PropTypes.bool.isrequired,
  children: PropTypes.node.isrequired,
  onClick: PropTypes.func.isrequired
}
 
export default Link
components/Footer.js
import React from 'react'
import FilterLink from '../containers/FilterLink'
import { VisibilityFilters } from '../actions'
 
const Footer = () => (
  <div>
    <span>Show: </span>
    <FilterLink filter={VisibilityFilters.SHOW_ALL}>All</FilterLink>
    <FilterLink filter={VisibilityFilters.SHOW_ACTIVE}>Active</FilterLink>
    <FilterLink filter={VisibilityFilters.SHOW_COMPLETED}>Completed</FilterLink>
  </div>
)
 
export default Footer
components/App.js
import React from 'react'
import Footer from './Footer'
import AddTodo from '../containers/AddTodo'
import VisibletodoList from '../containers/VisibletodoList'
 
const App = () => (
  <div>
    <AddTodo />
    <VisibletodoList />
    <Footer />
  </div>
)
 
export default App
容器组件
containers/VisibletodoList.js
import { connect } from 'react-redux'
import { toggletodo } from '../actions'
import TodoList from '../components/TodoList'
 
const getVisibletodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
    case 'SHOW_ALL':
    default:
      return todos
  }
}
 
const mapStatetoProps = state => ({
  todos: getVisibletodos(state.todos, state.visibilityFilter)
})
 
const mapdispatchToProps = dispatch => ({
  toggletodo: id => dispatch(toggletodo(id))
})
 
export default connect(
  mapStatetoProps,
  mapdispatchToProps
)(TodoList)
containers/FilterLink.js
import { connect } from 'react-redux'
import { setVisibilityFilter } from '../actions'
import Link from '../components/Link'
 
const mapStatetoProps = (state, ownProps) => ({
  active: ownProps.filter === state.visibilityFilter
})
 
const mapdispatchToProps = (dispatch, ownProps) => ({
  onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
})
 
export default connect(
  mapStatetoProps,
  mapdispatchToProps
)(Link)
其他组件
containers/AddTodo.js
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
 
const AddTodo = ({ dispatch }) => {
  let input
 
  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault()
          if (!input.value.trim()) {
            return
          }
          dispatch(addTodo(input.value))
          input.value = ''
        }}
      >
        <input ref={node => (input = node)} />
        <button type="submit">Add Todo</button>
      </form>
    </div>
  )
}
export default connect()(AddTodo)

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章