成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

todolist for react redux 學(xué)習(xí)總結(jié)

anquan / 2004人閱讀

摘要:為了提高自己的學(xué)習(xí)效率,避免做一些無(wú)用的工作,我也決定以后無(wú)論是工作還是學(xué)習(xí)一定要養(yǎng)成定時(shí)總結(jié)的習(xí)慣,而且也要用文字記錄下來(lái),這樣可以時(shí)常復(fù)習(xí),理清邏輯,加深印象。一種解決方法是將對(duì)象作為參數(shù),傳入容器組件。

前言
最近一直在學(xué)習(xí)react技術(shù)棧,相關(guān)的理論和概念基本都了解了,之前也用reactjs寫了幾個(gè)demo,切身體會(huì)到了函數(shù)式編程和組件化開(kāi)發(fā)的強(qiáng)大之處,但因各種主客觀原因,事后沒(méi)有對(duì)相關(guān)知識(shí)點(diǎn)進(jìn)行梳理和總結(jié),而且工作中也沒(méi)用到,導(dǎo)致現(xiàn)在復(fù)習(xí)的時(shí)候生疏了,還需要花大部分時(shí)間重新理清需求和邏輯,做了很多重復(fù)性的工作,太得不償失了。為了提高自己的學(xué)習(xí)效率,避免做一些無(wú)用的工作,我也決定以后(無(wú)論是工作還是學(xué)習(xí))一定要養(yǎng)成定時(shí)總結(jié)的習(xí)慣,而且也要用文字記錄下來(lái),這樣可以時(shí)常復(fù)習(xí),理清邏輯,加深印象。另外,關(guān)于我個(gè)人的學(xué)習(xí)總結(jié),如有不對(duì)的地方,歡迎批評(píng)指正,期待共同提高!不喜勿噴,謝謝!
第一章 頁(yè)面搭建 目錄結(jié)構(gòu)
├── components
|   └──app.css//樣式文件
├── node_modules //依賴包
├── static //靜態(tài)文件
|   └──index.html //入口html文件
|   └──bundle.js //編譯后的js文件
├── index.js //主入口js文件
├── package.json //項(xiàng)目所依賴的npm包
├── webpack.config.js //webpack配置文件
└── yarn.lock //依賴或者更新包相關(guān)版本信息。這樣可以解決同一個(gè)項(xiàng)目在不同機(jī)器上環(huán)境不一致的問(wèn)題。
包管理文件 package.json
{
  "name": "todolist",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --line --hot",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "www.icrazyman.cn",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "css-loader": "^0.28.4",
    "react": "^15.4.1",
    "react-dom": "^15.4.1",
    "style-loader": "^0.18.2",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2"
  },
  "dependencies": {
    "node": "^6.11.1"
  }
}
入口文件index.html



    
    Redux Todos Example


    
index.js
import第三方依賴包和css文件
import React from "react"
import { render } from "react-dom"
import "./components/app.css"

render(
  ,
  document.getElementById("root")
)
webpack配置文件webpack.config.js
module.exports = {
  devtool: "eval-source-map", //選擇map來(lái)增強(qiáng)調(diào)試過(guò)程
  entry: __dirname + "/index.js", //入口文件
  output: {
    path: __dirname + "/static",//打包生成路徑
    filename: "bundle.js" 
  },
  module: {
    loaders: [{
      test: /.js$/,
      exclude: /node_modules/,
      loader: "babel",
      query: {
        presets: ["es2015", "react"]
      }
    }, { test: /.css$/, loader: "style-loader!css-loader" }]
  },
  devServer: { //熱更新
    contentBase: "./static",
    historyApiFallback: true,
    inline: true,
    hot: true
  }
}
打開(kāi)終端運(yùn)行yarnnpm install安裝依賴,運(yùn)行npm run build編譯,運(yùn)行npm start進(jìn)行查看頁(yè)面是否正常顯示
小結(jié):這個(gè)階段只是把頁(yè)面實(shí)現(xiàn)出來(lái)了,還沒(méi)有實(shí)現(xiàn)任何邏輯。其中頁(yè)面實(shí)現(xiàn)的步驟為:
1. 在index.html編寫html結(jié)構(gòu)和css樣式
2. 把html結(jié)構(gòu)提取到index.js組件中同時(shí)轉(zhuǎn)換成jsx語(yǔ)法
3. 把css樣式提取到app.css中

第二章 引入redux組件化 目錄結(jié)構(gòu)
├── actions
|   └──index.js//管理狀態(tài)
├── components
|   └──app.css//樣式文件
|   └──App.js//UI組件入口文件
|   └──Link.js//UI組件
|   └──Todo.js//UI組件
|   └──Top.js//UI組件
├── containers
|   └──VisibleTodoList.js//容器組件
|   └──AddTodo.js//容器組件
|   └──FilterLink.js//容器組件
├── reducers
|   └──index.js//數(shù)據(jù)邏輯處理文件
├── node_modules //依賴包
├── static //靜態(tài)文件
|   └──index.html //入口html文件
|   └──bundle.js //編譯后的js文件
├── index.js //主入口js文件
├── package.json //項(xiàng)目所依賴的npm包
├── webpack.config.js //webpack配置文件
└── yarn.lock //依賴或者更新包相關(guān)版本信息。這樣可以解決同一個(gè)項(xiàng)目在不同機(jī)器上環(huán)境不一致的問(wèn)題。
安裝依賴包
此次新增react-redux和redux依賴包
{
  "name": "todolist",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "start": "webpack-dev-server --line --hot",
    "test": "echo "Error: no test specified" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.21.0",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "css-loader": "^0.28.4",
    "react": "^15.4.1",
    "react-dom": "^15.4.1",
    "react-redux": "^5.0.1",
    "redux": "^3.6.0",
    "style-loader": "^0.18.2",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2"
  },
  "dependencies": {
    "node": "^6.11.1"
  }
}
index.js
此次利用redux管理整個(gè)項(xiàng)目的狀態(tài),并且把項(xiàng)目代碼抽離成組件
//注意:import后不加{}代表引入的default,加了{(lán)}代表引入其中導(dǎo)出的一部分,用到了ES6的解構(gòu)
//注意:import后不加{}代表引入的default,加了{(lán)}代表引入其中導(dǎo)出的一部分,用到了ES6的解構(gòu)
import React from "react"
import { render } from "react-dom"
import { Provider } from "react-redux"
import { createStore } from "redux"
//數(shù)據(jù)邏輯處理保存在reducers里
import todoApp from "./reducers"
import App from "./components/App"
//在頂層創(chuàng)建store管理整個(gè)項(xiàng)目的數(shù)據(jù)
const store = createStore(todoApp)
console.log("9. root index start")
//connect方法生成容器組件以后,需要讓容器組件拿到state對(duì)象,才能生成 UI 組件的參數(shù)。
// 一種解決方法是將state對(duì)象作為參數(shù),傳入容器組件。但是,這樣做比較麻煩,尤其是容器組件可能在很深的層級(jí),一級(jí)級(jí)將state傳下去就很麻煩。
// React-Redux 提供Provider組件,可以讓容器組件拿到state。
//Provider在根組件外面包了一層,這樣一來(lái),App的所有子組件就默認(rèn)都可以拿到state了。
render(
  
    
  
  ,document.getElementById("root")
)
console.log("9. root index end")
reducers/index.js
把數(shù)據(jù)邏輯處理的代碼抽離成reducers
import { combineReducers } from "redux"
console.log("data flow:")
console.log("1. reducers start")
/* 傳入舊的state和作用的action返回一個(gè)新state */
const todo = (state, action) => {
    console.log("data flow 4")
    switch(action.type) {
        case "ADD_TODO":
            return {
                id: action.id,
                text: action.text,
                completed: false    //新增默認(rèn)為未完成
            }
        case "TOGGLE_TODO":
            if (state.id !== action.id) {
                return state
            }
            return Object.assign({}, state, {completed: !state.completed})
        default:
            return state
    }
}

const todos = (state = [], action) => {
    console.log("1.1 todos twice")
    switch(action.type) {
        case "ADD_TODO":
            return [
                ...state,
                todo(undefined, action)
            ]
            //todo(undefined, action) 新增一條記錄時(shí)第一個(gè)參數(shù)state不存在
        case "TOGGLE_TODO":
            return state.map(t => todo(t, action));
        default:
            return state;
    }
}

const visibilityFilter = (state = "SHOW_ALL", action) => {
    console.log("1.2 visibilityFilter twice")
    switch (action.type) {
        case "SET_VISIBILITY":
            return action.filter;
        default:
            return state;
    }
}
console.log("1. reducers end")
export default combineReducers({
    todos,
    visibilityFilter
});
actions/index.js
在redux中,actions是觸發(fā)store中數(shù)據(jù)更新的唯一來(lái)源,所以要寫個(gè)actions利用dispatch方法來(lái)觸發(fā)store中管理的狀態(tài)更新
let nextTodoId = 0;
console.log("2. actions start")

// 添加
const addTodo = (text) => {
    // console.log("text:" + text)
    console.log("data flow 2")
    let id = nextTodoId ++ ;
    return {
        type: "ADD_TODO",
        id: id,
        text
    }
}

// 頂部顯示狀態(tài)
const setVisibility = (filter) => {
    // console.log("filter:" + filter)
    return {
        type: "SET_VISIBILITY",
        filter
    }
}

// 觸發(fā)
const toggleTodo = (id) => {
    // console.log("id:" + id)
    return {
        type: "TOGGLE_TODO",
        id
    }
}
export {addTodo, setVisibility, toggleTodo}
console.log("2. actions end")
components/App.js
子組件的入口文件,負(fù)責(zé)對(duì)抽離出的子組件進(jìn)行組合然后導(dǎo)出
import React from "react"
import Top from "./Top"
import VisibleTodoList from "../containers/VisibleTodoList"
import AddTodo from "../containers/AddTodo"
import "./app.css"
console.log("8. App.js start")
const App = () => (
  
) console.log("8. App.js end") export default App;
components/Top.js
TodoList頂部組件
import React from "react"
import { connect } from "react-redux"
import { setVisibility } from "../actions"
import FilterLink from "../containers/FilterLink"
console.log("4. Top.js start")

const Top = () => (
    
全部任務(wù) 待辦任務(wù) 已完成任務(wù)
); console.log("4. Top.js end") export default Top;
containers/FilterLink.js
過(guò)濾組件
import React from "react"
import { connect } from "react-redux"
import { setVisibility } from "../actions"
import Link from "../components/Link"
//第二個(gè)參數(shù)表示組件自身的props
//mapStateToProps()將state節(jié)點(diǎn)注入到與view相關(guān)的組件
const mapStateToProps = (state, ownProps) => {
    // console.log({state,ownProps})
    return {
        active: ownProps.filter === state.visibilityFilter
    }
}
//mapDispatchToProps()將需要綁定的響應(yīng)事件注入到組件上
const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        onClick: () => {
            dispatch(setVisibility(ownProps.filter))
        }
    }
}
//connent()函數(shù)生成容器組件
const FilterLink = connect(
    mapStateToProps,
    mapDispatchToProps
)(Link)

export default FilterLink;
components/Link.js
展示組件,顯示頂部狀態(tài)按鈕
import React from "react";
console.log("3. Link.js start")
const Link = ({ active, children, onClick }) => {
    return (
        
    )
}
console.log("3. Link.js end")
export default Link;
components/Todo.js
每一個(gè)Todo子組件
import React from "react"
console.log("5. Todo.js start")
//UI 組件有以下幾個(gè)特征。
// 只負(fù)責(zé) UI 的呈現(xiàn),不帶有任何業(yè)務(wù)邏輯
// 沒(méi)有狀態(tài)(即不使用this.state這個(gè)變量)
// 所有數(shù)據(jù)都由參數(shù)(this.props)提供
// 不使用任何 Redux 的 API
// UI 組件又稱為"純組件",不含狀態(tài),純粹由參數(shù)決定它的值
const Todo = ({ onClick, completed, text }) => (
  
  • {text}
  • ) console.log("5. Todo.js end") export default Todo;
    containers/VisibleTodoList.js
    TodoList列表組件
    import React from "react"
    import Todo from "../components/Todo"
    import { connect } from "react-redux"
    import { toggleTodo } from "../actions"
    console.log("6. VisibleTodoList start")
    //負(fù)責(zé)管理數(shù)據(jù)和業(yè)務(wù)邏輯,不負(fù)責(zé) UI 的呈現(xiàn)
    // 帶有內(nèi)部狀態(tài)
    // 使用 Redux 的 API
    const getVisibleTodos = (todos, filter) => {
        console.log("9.2 getVisibleTodos")
        switch (filter) {
            case "SHOW_ALL":
                return todos;
            case "SHOW_COMPLETED":
                return todos.filter(t => t.completed === true)//已完成
            case "SHOW_ACTIVE":
                return todos.filter(t => t.completed === false)//未完成
            default:
                throw new Error("Unknown filter: " + filter)
        }
    }
    //合并redux的狀態(tài)到react的props中
    //將state映射到 UI 組件的參數(shù)(props)
    //mapStateToProps會(huì)訂閱 Store,每當(dāng)state更新的時(shí)候,就會(huì)自動(dòng)執(zhí)行,重新計(jì)算 UI 組件的參數(shù),從而觸發(fā) UI 組件的重新渲染。
    //mapStateToProps的第一個(gè)參數(shù)總是state對(duì)象,還可以使用第二個(gè)參數(shù),代表容器組件的props對(duì)象。
    //使用ownProps作為參數(shù)后,如果容器組件的參數(shù)發(fā)生變化,也會(huì)引發(fā) UI 組件重新渲染。
    const mapStateToProps = (state, ownProps) => {
        console.log("9.1 mapStateToProps")
        // console.log(ownProps)
        // console.log(state)
        return {
            todos: getVisibleTodos(state.todos, state.visibilityFilter)
        }
    }
    //將用戶對(duì) UI 組件的操作映射成 Action
    //建立 UI 組件的參數(shù)到store.dispatch方法的映射。也就是說(shuō),它定義了哪些用戶的操作應(yīng)該當(dāng)作 Action,傳給 Store。它可以是一個(gè)函數(shù),也可以是一個(gè)對(duì)象
    //如果mapDispatchToProps是一個(gè)函數(shù),會(huì)得到dispatch和ownProps(容器組件的props對(duì)象)兩個(gè)參數(shù)。
    //mapDispatchToProps作為函數(shù),應(yīng)該返回一個(gè)對(duì)象,該對(duì)象的每個(gè)鍵值對(duì)都是一個(gè)映射,定義了 UI 組件的參數(shù)怎樣發(fā)出 Action。
    //如果mapDispatchToProps是一個(gè)對(duì)象,它的每個(gè)鍵名也是對(duì)應(yīng) UI 組件的同名參數(shù),鍵值應(yīng)該是一個(gè)函數(shù),會(huì)被當(dāng)作 Action creator ,返回的 Action 會(huì)由 Redux 自動(dòng)發(fā)出。
    const mapDispatchToProps = (dispatch) => {
        return {
            onTodoClick: (id) => {
                // console.log(id)
                dispatch(toggleTodo(id))
            }
        }
    }
    
    const TodoList = ({ todos, onTodoClick }) => {
        console.log("9.3 TodoList")
        // console.log(todos);//todos數(shù)組
        return (
            
      {todos.map(todo => onTodoClick(todo.id)} /> )}
    ) } //React-Redux 提供connect方法,用于從 UI 組件生成容器組件。connect的意思,就是將這兩種組件連起來(lái)。 //connect方法接受兩個(gè)參數(shù):mapStateToProps和mapDispatchToProps。它們定義了 UI 組件的業(yè)務(wù)邏輯。前者負(fù)責(zé)輸入邏輯,即將state映射到 UI 組件的參數(shù)(props),后者負(fù)責(zé)輸出邏輯,即將用戶對(duì) UI 組件的操作映射成 Action。 //connect方法可以省略mapStateToProps參數(shù),那樣的話,UI 組件就不會(huì)訂閱Store,就是說(shuō) Store 的更新不會(huì)引起 UI 組件的更新。 const VisibleTodoList = connect( mapStateToProps, mapDispatchToProps )(TodoList) console.log("6. VisibleTodoList end") export default VisibleTodoList;
    containers/AddTodo.js
    添加Todo子組件
    import React from "react"
    import { connect } from "react-redux"
    import { addTodo } from "../actions"
    console.log("7. AddTodo.js start")
    let AddTodo = ({ dispatch }) => {
        let input;
        return (
            
    { console.log("data flow 1") e.preventDefault(); if (!input.value.trim()) { return } dispatch(addTodo(input.value)) input.value = "" } }> input = r } className="todo-input" autoFocus={true}/>
    ) } AddTodo = connect()(AddTodo)//把a(bǔ)ddTodo用redux的connect方法重新包裝一下,使其可使用state中的數(shù)據(jù) console.log("7. AddTodo.js end") export default AddTodo;
    打開(kāi)終端運(yùn)行yarnnpm install安裝依賴,運(yùn)行npm run build編譯,運(yùn)行npm start進(jìn)行查看頁(yè)面和功能是否正常
    小結(jié):這個(gè)階段把頁(yè)面和功能實(shí)現(xiàn)出來(lái)了,初步把整個(gè)項(xiàng)目抽離成組件,也利用redux把代碼業(yè)務(wù)邏輯處理、狀態(tài)管理和狀態(tài)分發(fā)管理分離出來(lái)了

    總結(jié):本次todolist的項(xiàng)目因時(shí)間關(guān)系中間斷了兩次,也算是“因禍得?!卑桑∥乙舶堰@個(gè)項(xiàng)目完整地復(fù)習(xí)了一遍。這個(gè)項(xiàng)目主要把redux的運(yùn)用以及數(shù)據(jù)流了解了下,算是大概清楚怎么玩了,為什么說(shuō)大概呢?一個(gè)是因?yàn)槟壳肮ぷ髦袥](méi)有使用,無(wú)法運(yùn)用到實(shí)際項(xiàng)目中,一個(gè)就是最外層的index.js,不明白為什么console.log是最后打印出來(lái)的,也就意味這是最后加載這個(gè)文件的,這個(gè)文件我的理解不應(yīng)該是整個(gè)項(xiàng)目js的主入口文件嗎?為什么反而最后加載呢?不明白,先記下來(lái)吧,等以后用到redux了再有意識(shí)地研究一下。現(xiàn)在把自己做這個(gè)項(xiàng)目的詳細(xì)步驟、個(gè)人理解以及查閱相關(guān)的資料整理出來(lái)了,不一定十分準(zhǔn)確,如果有哪位大神有不同的意見(jiàn)歡迎批評(píng)指正!最新了解了react,很喜歡它的組件化開(kāi)發(fā),奈何公司用的卻是JQ,所以在react里我其實(shí)還只是個(gè)新手,不喜勿噴?。?

    文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94814.html

    相關(guān)文章

    • Redux 基礎(chǔ) - react 全家桶學(xué)習(xí)筆記(一)

      摘要:二基礎(chǔ)就是一個(gè)普通的。其他屬性用來(lái)傳遞此次操作所需傳遞的數(shù)據(jù),對(duì)此不作限制,但是在設(shè)計(jì)時(shí)可以參照標(biāo)準(zhǔn)。對(duì)于異步操作則將其放到了這個(gè)步驟為添加一個(gè)變化監(jiān)聽(tīng)器,每當(dāng)?shù)臅r(shí)候就會(huì)執(zhí)行,你可以在回調(diào)函數(shù)中使用來(lái)得到當(dāng)前的。 注:這篇是16年10月的文章,搬運(yùn)自本人 blog...https://github.com/BuptStEve/... 零、環(huán)境搭建 參考資料 英文原版文檔 中文文檔 墻...

      aaron 評(píng)論0 收藏0
    • dva框架使用詳解及Demo教程

      摘要:框架的使用詳解及教程在前段時(shí)間,我們也學(xué)習(xí)講解過(guò)框架的基本使用,但是有很多同學(xué)在交流群里給我的反饋信息說(shuō),框架理解上有難度,看了之后還是一臉懵逼不知道如何下手,很多同學(xué)就轉(zhuǎn)向選擇使用框架。 dva框架的使用詳解及Demo教程 在前段時(shí)間,我們也學(xué)習(xí)講解過(guò)Redux框架的基本使用,但是有很多同學(xué)在交流群里給我的反饋信息說(shuō),redux框架理解上有難度,看了之后還是一臉懵逼不知道如何下手,很...

      bergwhite 評(píng)論0 收藏0
    • 實(shí)例講解react+react-router+redux

      摘要:而函數(shù)式編程就不一樣了,這是模仿我們?nèi)祟惖乃季S方式發(fā)明出來(lái)的。數(shù)據(jù)流在中,數(shù)據(jù)的流動(dòng)是單向的,即從父節(jié)點(diǎn)傳遞到子節(jié)點(diǎn)。數(shù)據(jù)流嚴(yán)格的單向數(shù)據(jù)流是架構(gòu)的設(shè)計(jì)核心。 前言 總括: 本文采用react+redux+react-router+less+es6+webpack,以實(shí)現(xiàn)一個(gè)簡(jiǎn)易備忘錄(todolist)為例盡可能全面的講述使用react全家桶實(shí)現(xiàn)一個(gè)完整應(yīng)用的過(guò)程。 代碼地址:Re...

      RiverLi 評(píng)論0 收藏0
    • TypeScript 3.0 + React + Redux 最佳實(shí)踐

      摘要:首先聲明這篇文章是想說(shuō)明一下最新版本的的新特性帶來(lái)的極大的開(kāi)發(fā)體驗(yàn)提升而不是如何利用開(kāi)發(fā)應(yīng)用這個(gè)特性就是對(duì)的支持在的中有說(shuō)明具體可以參考這里在版本之前我們?cè)陂_(kāi)發(fā)應(yīng)用尤其是在配合一類庫(kù)的時(shí)候經(jīng)常用到諸如之類的封裝而這些函數(shù)其實(shí)都可以用裝飾器的 首先聲明, 這篇文章是想說(shuō)明一下最新版本的 TypeScript(3.0) 的新特性帶來(lái)的極大的 React 開(kāi)發(fā)體驗(yàn)提升. 而不是如何利用 Ty...

      CloudwiseAPM 評(píng)論0 收藏0
    • 你要的 React 面試知識(shí)點(diǎn),都在這了

      摘要:是流行的框架之一,在年及以后將會(huì)更加流行。于年首次發(fā)布,多年來(lái)廣受歡迎。下面是另一個(gè)名為的高階函數(shù)示例,該函數(shù)接受另外兩個(gè)函數(shù),分別是和。將所有較小的函數(shù)組合成更大的函數(shù),最終,得到一個(gè)應(yīng)用程序,這稱為組合。 React是流行的javascript框架之一,在2019年及以后將會(huì)更加流行。React于2013年首次發(fā)布,多年來(lái)廣受歡迎。它是一個(gè)聲明性的、基于組件的、用于構(gòu)建用戶界面的高...

      klinson 評(píng)論0 收藏0

    發(fā)表評(píng)論

    0條評(píng)論

    最新活動(dòng)
    閱讀需要支付1元查看
    <