zoukankan      html  css  js  c++  java
  • Redux Todos Example

    此项目模板是使用Create React App构建的,它提供了一种简单的方法来启动React项目而无需构建配置。
    使用Create-React-App构建的项目包括对ES6语法的支持,以及几种非官方/尚未最终形式的Javascript语法
    先看效果

    这个例子可以帮助你深入理解在 Redux 中 state 的更新与组件是如何共同运作的。
    展示了 reducer 如何委派 action 给其它 reducer,也展示了如何使用 React Redux 从展示组件中生成容器组件。

    //index.js 跟组件
    import React from 'react'
    import { render } from 'react-dom'
    import { createStore } from 'redux'
    import { Provider } from 'react-redux'
    import App from './components/App'
    import rootReducer from './reducers'
    
    const store = createStore(rootReducer)
    
    render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.getElementById('root')
    )
    
    

    先看action,action是对象

    let nextTodoId = 0
    // Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。
    // 多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
    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'
    }
    
    

    接下来看reducer
    这个是combineReducers

    import { combineReducers } from 'redux'
    import todos from './todos'
    import visibilityFilter from './visibilityFilter'
    
    export default combineReducers({
      todos,
      visibilityFilter
    })
    
    

    这个是reducer操作纯函数

    //纯函数操作state
    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
    
    

    visibilityFilter.js中是进行过滤函数

    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
    
    
    //app.js
    //这个是根APP组件
    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
    

    这个是footer.js

    //这是一个footer组件
    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
    
    //link组件
    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
    
    
    //todo组件
    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
    
    

    这个是todoList组件

    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
    

    接下来展示了如何使用 React Redux 从展示组件中生成容器组件。
    在container中的是AddTodo.js

    //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)
    
    
    //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)
    
    //VisibleTodoList.js
    import { connect } from 'react-redux'
    import { toggleTodo } from '../actions'
    import TodoList from '../components/TodoList'
    import { VisibilityFilters } from '../actions'
    
    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)
        default:
          throw new Error('Unknown filter: ' + filter)
      }
    }
    
    const mapStateToProps = state => ({
      todos: getVisibleTodos(state.todos, state.visibilityFilter)
    })
    
    const mapDispatchToProps = dispatch => ({
      toggleTodo: id => dispatch(toggleTodo(id))
    })
    
    export default connect(
      mapStateToProps,
      mapDispatchToProps
    )(TodoList)
    
  • 相关阅读:
    JS-字符串截取方法slice、substring、substr的区别
    Vue中computed和watch的区别
    Vue响应式原理及总结
    JS实现深浅拷贝
    JS中new操作符源码实现
    点击页面出现爱心效果
    js判断对象是否为空对象的几种方法
    深入浅出js实现继承的7种方式
    es6-class
    详解 ESLint 规则,规范你的代码
  • 原文地址:https://www.cnblogs.com/smart-girl/p/10782616.html
Copyright © 2011-2022 走看看