我是靠谱客的博主 英勇可乐,最近开发中收集的这篇文章主要介绍解析react-redux官方案例todo,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我相信很多小伙伴在学习react-redux都会涉及到一个todo的官方案例,不过刚刚开始接触的人可能看十几次都没感觉,现在我本人对它的总结下

一、项目的构建

  • 1、本项目我使用前端脚手架yeoman构建参考
  • 2、创建一个todo项目

    yo react-webpack
  • 3、安装别的依赖包

    npm install redux --save
    npm install react-redux --save
    npm install redux-thunk --save
    
  • 4、把刚刚构建的项目运行

    npm run serve
  • 5、在浏览器上访问

    localhost:8000

二、运行后项目效果图

这里写图片描述

三、项目组件拆分

  • 1、上面输入框与添加按钮拆分为一个组件AddTodo
  • 2、中间显示的拆分一个组件TodoList
  • 3、底部分类拆分一个组件Link

四、todo项目的开发

  • 1、项目结构(关心我圈住的就可以)

    这里写图片描述

  • 2、根据redux构建项目的方式创建几个文件夹如不清楚请参考
  • 3、开发流程(一般开发流程)

    这里写图片描述

五、AddTodo组件的开发

  • 1、创建action(如果项目大,可以一个组件写一个action.js)

    /**
    * 定义todo项目的action
    */
    'use strict';
    let nextTodo = 0;
    // 一般外面需要使用的会定义常量
    export const ADD_TODO = 'ADD_TODO';
    export const TOGGLE_TODO = 'TOGGLE_TODO';
    // 定义一个添加的action
    export const addTodo = (text) => ({
    type: ADD_TODO,
    id: nextTodo++,
    text
    });
    // 定义一个切换的action
    export const toggleTodo = (id) => ({
    type: TOGGLE_TODO,
    id
    })
  • 2、AddTodo组件的reducer的书写

    项目需要可以一个组件写一个reducer.js然后用combineReducers合并在一起

    import { combineReducers } from 'redux';
    import { ADD_TODO, TOGGLE_TODO} from './../actions/index';
    const todos = (state = [], action) => {
    switch (action.type) {
    case ADD_TODO:
    return [
    ...state,
    {
    id: action.id,
    text: action.text,
    completed: false
    }
    ];
    case TOGGLE_TODO:
    // 定义切换的,如果当前点击的id等于传递进来的id就改变状态,否则就不边
    return state.map(todo => {
    if (todo.id === action.id) {
    return { ...todo, completed: !todo.completed }
    } else {
    return todo;
    }
    })
    default:
    return state;
    }
    }
  • 3、书写展示组件

    ...
    render() {
    // console.log(this.props);
    return (
    <div>
    <input type="text" placeholder="请输入内容" ref="myinput"/>
    <input type="button" value="添加" onClick={this.addTodo} />
    </div>
    )
    }
    ...
  • 4、容器组件(如果对块还有不清楚请参考)

    'use strict'
    /**
    * 定义AddTodo的容器组件
    */
    import {connect} from 'react-redux';
    import AddTodo from './../components/AddTodo';
    // 这样全部的导入的就有点浪费,在AddTodo中只用了一个addTodo方法
    // import * as ActionCreators from './../actions/index';
    import {addTodo} from './../actions';
    export default connect(
    state=>({todos:state.todos}),
    // ActionCreators
    dispatch =>({
    addTodo:(text)=>dispatch(addTodo(text))
    })
    )(AddTodo);
  • 5、容器组件传递了todosaddTodo到展示组件,再看展示组件的完整代码

    /**
    * AddTodo展示组件
    */
    'use strict'
    import React, { Component } from 'react';
    export default class AddTodo extends Component {
    constructor(props) {
    super(props);
    this.addTodo = this.addTodo.bind(this);
    }
    render() {
    // console.log(this.props);
    return (
    <div>
    <input type="text" placeholder="请输入内容" ref="myinput"/>
    <input type="button" value="添加" onClick={this.addTodo} />
    </div>
    )
    }
    // 增加的todo的方法
    addTodo() {
    const { addTodo } = this.props;
    // 获取到input的dom节点
    let myinputDom = this.refs.myinput;
    // 发送完成后就清空输入框
    addTodo(myinputDom.value);
    myinputDom.value = '';
    }
    }
    // 约束数据类型
    AddTodo.protoTypes = {
    addTodo: React.PropTypes.func.isRequired
    }
  • 6、组装到项目中试跑(本项目中创建了一个入口的App.js来统一管理)

    import 'core-js/fn/object/assign';
    import React from 'react';
    import ReactDOM from 'react-dom';
    import {createStore,applyMiddleware} from 'redux';
    import thunk from 'redux-thunk';
    import {Provider} from 'react-redux';
    import todoApp from './reducers/index';
    import App from './components/App';
    let store = createStore(todoApp,applyMiddleware(thunk));
    // Render the main component into the dom
    ReactDOM.render(
    <Provider store={store}>
    <App />
    </Provider>
    , document.getElementById('app'));
    /**
    * 主文件入口
    */
    'use strict'
    import React, { Component } from 'react';
    import AddTodoConnect from './../containers/AddTodoConnect';
    export default class App extends Component {
    constructor(props){
    super(props);
    }
    render() {
    return (
    <div>
    <AddTodoConnect/>
    </div>
    )
    }
    }

六、显示添加的todo组件

  • 1、展示组件(就是接受props数组便利出来)

    /**
    * todo的展示组件
    */
    'use strict'
    import React, { Component } from 'react';
    // 引入样式
    require('styles/todolist.css');
    export default class TodoList extends Component {
    constructor(props) {
    super(props);
    }
    render() {
    const { todos, toggleTodo } = this.props;
    return (
    <ul>
    {
    todos.map(todo => (
    // 注意这个地方不能直接写onClik = {toggleTodo},这样的意思是立即执行
    //<li key={todo.id} onClick={()=>toggleTodo(todo.id)} style={{
    //textDecoration: todo.completed ? 'line-through' : 'none',
    //color: todo.completed ? 'red' : 'black'
    //}}>{todo.text}</li>
    <li key={todo.id} onClick={() => toggleTodo(todo.id)} className={todo.completed ? 'list-select' : 'list'}>{todo.text}</li>
    ))
    }
    </ul>
    )
    }
    }
    // 约束数据类型
    TodoList.protoTypes = {
    todos: React.PropTypes.object.isRequired,
    toggleTodo:React.PropTypes.func.isRequired
    }
  • 2、对应的容器组件

    /**
    * TodoList的容器组件
    */
    'use strict'
    import { connect } from 'react-redux';
    import TodoList from './../components/TodoList';
    import { toggleTodo } from './../actions/index';
    export default connect(
    state => ({ todos: state.todos}),
    dispatch => ({
    toggleTodo: (id) => dispatch(toggleTodo(id))
    })
    )(TodoList);
  • 3、组装到App.js

七、底部的组件

  • 1、在action里面添加

    ...
    export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER';
    export const SHOW_ALL = 'SHOW_ALL';
    // 定义一个是否显示的action,每次发送出去的的type是一样的
    export const setVisibilityFilter = (filter) => ({
    type: SET_VISIBILITY_FILTER,
    filter
    })
  • 2、在reducer里面添加

    // 定义一个底部选择的reducer
    const visibilityFilter = (state = SHOW_ALL,action) => {
    switch(action.type){
    case SET_VISIBILITY_FILTER:
    return action.filter
    default:
    return state
    }
    }
    // 利用redux里面的combineReducers合并所有的reducer
    const todoApp = combineReducers({
    todos,
    visibilityFilter
    })
    // 默认导出
    export default todoApp;
  • 3、定义展示组件

    /**
    * 定义一个底部现在的展示组件
    */
    'use strict'
    import React, { Component } from 'react'
    // 引入样式
    require('styles/link.css');
    export default class Link extends Component {
    constructor(props) {
    super(props);
    }
    render() {
    const { active, children, onClick } = this.props;
    if (active) {
    return <span>{children}</span>
    } else {
    return (
    <a href="javascript:void(0)" onClick={()=>onClick()}>{children}</a>
    )
    }
    }
    }
  • 4、定义容器组件(关于ownProps参考)

    /**
    * 定义Link的容器组件
    */
    import { connect } from 'react-redux';
    import Link from './../components/Link.js';
    import { setVisibilityFilter } from './../actions/index';
    const mapStateToProps = function(state, ownProps){
    console.log('ownProps--->',ownProps);
    return {
    active: ownProps.filter === state.visibilityFilter
    }
    }
    const mapDispatchToProps = (dispatch, ownProps) => ({
    onClick: () => {
    dispatch(setVisibilityFilter(ownProps.filter))
    }
    })
    /**下面这样也可以
    * (state, ownProps) => ({
    active: ownProps.filter === state.visibilityFilter
    }),
    (dispatch,ownProps) => ({
    onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
    })
    */
    export default connect(
    mapStateToProps,
    mapDispatchToProps
    )(Link);
    
  • 5、修改之前显示的todo组件(容器组件)

    **
    * 定义一个过滤的方法
    */
    const getVisibleTodos = (todos, filter) => {
    switch(filter){
    case 'SHOW_ALL':
    return todos;
    case 'SHOW_ACTIVE': //未完成
    return todos.filter(todo => !todo.completed);
    case 'SHOW_COMPLETED': // 已完成
    return todos.filter(todo => todo.completed);
    default:
    return todos;
    }
    }
    export default connect(
    // 传递到展示组件的数据过滤了
    state => ({ todos: getVisibleTodos(state.todos,state.visibilityFilter)}),
    dispatch => ({
    toggleTodo: (id) => dispatch(toggleTodo(id))
    })
    )(TodoList);

八、demo下载地址

最后

以上就是英勇可乐为你收集整理的解析react-redux官方案例todo的全部内容,希望文章能够帮你解决解析react-redux官方案例todo所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部