摘要:上一篇也許是最佳小實(shí)踐加入在組件之間流通數(shù)據(jù)更確切的說(shuō),這被叫做單向數(shù)據(jù)流數(shù)據(jù)沿著一個(gè)方向從父組件流到子組件。這個(gè)將這個(gè)新的對(duì)象附加到上,并將它返回,用來(lái)更新。這一次,將當(dāng)前的狀態(tài)仍舊是空數(shù)組和對(duì)象一起傳遞給了。
上一篇:react、react-router、redux 也許是最佳小實(shí)踐1
加入 reduxReact 在組件之間流通數(shù)據(jù).更確切的說(shuō),這被叫做“單向數(shù)據(jù)流”——數(shù)據(jù)沿著一個(gè)方向從父組件流到子組件。由于這個(gè)特性,對(duì)于沒(méi)有父子關(guān)系的兩個(gè)組件之間的數(shù)據(jù)交流就變得不是那么顯而易見。這里 Redux 就排上用場(chǎng)了。Redux提供了一個(gè)解決方案,通過(guò)將應(yīng)用程序所有的狀態(tài)都存儲(chǔ)在一個(gè)地方,叫做“store”。然后組件就可以“dispatch”狀態(tài)的改變給這個(gè)store,而不是直接跟另外的組件交流。所有的組件都應(yīng)該意識(shí)到狀態(tài)的改變可以“subscribe”給store。如下圖:
原理講完,下面開始加入代碼。
先看看一個(gè)小例子。
開始之前,需要先用 Redux.createStore() 創(chuàng)建一個(gè)store,然后將所有的reducer作為參數(shù)傳遞進(jìn)去,讓我們看一下這個(gè)只傳遞了一個(gè)reducer的小例子:
var userReducer = function(state, action) { if (state === undefined) { state = []; } if (action.type === "ADD_USER") { state.push(action.user); } return state; } var store = Redux.createStore(userReducer); store.dispatch({ type: "ADD_USER", user: {name: "xiaoming"} });
上面的程序干了些什么呢:
這個(gè)store只由一個(gè)reducer創(chuàng)建。
這個(gè)reducer 初始化狀態(tài)的時(shí)候使用了一個(gè)空數(shù)組 。*
在被分派的這個(gè)action里面使用了新的user對(duì)象。
這個(gè)reducer將這個(gè)新的user對(duì)象附加到state上,并將它返回,用來(lái)更新store。
*在這個(gè)例子里reducer實(shí)際上被調(diào)用了兩次 —— 一次是在創(chuàng)建store的時(shí)候,一次是在分派action之后。
當(dāng)store被創(chuàng)建之后,Redux立即調(diào)用了所有的reducer,并且將它們的返回值作為初始狀態(tài)。第一次調(diào)用reducer傳遞了一個(gè) undefined 給state。經(jīng)過(guò)reducer內(nèi)部的代碼處理之后返回了一個(gè)空數(shù)組給這個(gè)store的state作為開始。
所有的reducer在每次action被分派之后都會(huì)被調(diào)用。因?yàn)?b>reducer返回的狀態(tài)將會(huì)成為新的狀態(tài)存儲(chǔ)在store中,所以 Redux總是希望所有的reducer都要返回一個(gè)狀態(tài)。
在這個(gè)例子中,reducer第二次的調(diào)用發(fā)生在分派之后。記住,一個(gè)被分派的action描述了一個(gè)改變狀態(tài)的意圖,而且通常攜帶有數(shù)據(jù)用來(lái)更新狀態(tài)。這一次,Redux將當(dāng)前的狀態(tài)(仍舊是空數(shù)組)和action對(duì)象一起傳遞給了reducer。這個(gè)action對(duì)象,現(xiàn)在有了一個(gè)值為1ADD_USER的type屬性, 讓reducer知道怎樣改變狀態(tài)。
正式redux登場(chǎng)在 src 下面創(chuàng)建一個(gè) redux、actions、 data(存放一些初始數(shù)據(jù))文件夾,然后在 data文件夾下面創(chuàng)建一個(gè)db.js,這個(gè)文件寫上一些初始的數(shù)據(jù):
src/data/db.js
const data = [ { id: 1, title: "明天要去打醬油", content: "系呀系呀我們一起打醬油" }, { id: 2, title: "周末去書吧讀書", content: "書籍是人類進(jìn)步的階梯" }, { id: 3, title: "備份一下數(shù)據(jù)庫(kù)", content: "備份服務(wù)器的數(shù)據(jù)庫(kù),一般都是分開的,分布式數(shù)據(jù)庫(kù)" }, { id: 4, title: "周五記得把被子洗了", content: "洗杯子被子被子被子" }, { id: 5, title: "計(jì)劃五", content: "計(jì)劃五內(nèi)容" } ] export default data
好了,初始的數(shù)據(jù)我們有了,下面就是創(chuàng)建 store 了,在redux文件夾下面,創(chuàng)建一個(gè)planlist.js文件,這個(gè)文件就是操作 store 的動(dòng)作 action集合處理的數(shù)據(jù),這時(shí)候我們會(huì)去action文件夾下面新建,action-type.js 和plan.js,代碼如下:
src/action/action-type.js
export const ADD = "ADD"; export const DELECT = "DELECT"; export const SHOW = "SHOW";
src/action/plan.js
import * as types from "./action-type.js"; // 添加計(jì)劃 export function addPlan(item) { return { type: types.ADD, item }; } // 刪除計(jì)劃 export function deletePlan(id) { return { type: types.DELECT, id }; } // 顯示隱藏彈層 export function show(show) { return { type: types.SHOW, show }; }
action 我們都定義好了現(xiàn)在我們就可以改變 store了。寫好我們的 reducer
src/redux/planlist.js
import * as types from "../actions/action-type.js"; import data from "../data/db.js" const initialState = { show: false, // 是否顯示彈出 planlist: data // 初始的計(jì)劃表 }; const planReducer = function(state = initialState, action) { let list = state.planlist; switch(action.type) { // 添加計(jì)劃 case types.ADD: list.push(action.item); return Object.assign({}, state, { planlist: list }); // 刪除計(jì)劃 case types.DELECT: let newstate = list.filter((item) => item.id != action.id); return Object.assign({}, state, { planlist: newstate });; // 顯示、隱藏彈出層 case types.SHOW: return Object.assign({}, state, { show: action.show }); } return state; } export default planReducer;
在redux 下面再創(chuàng)建reducers.js和store.js,
src/redux/reducers.js
import { combineReducers } from "redux"; // Reducers import planlist from "./planlist"; // Combine Reducers var reducers = combineReducers({ planlist: planlist }); export default reducers;
src/redux/store.js
import { createStore } from "redux"; import reducers from "./reducers.js"; const store = createStore(reducers); export default store;
這會(huì)我們的 store 就完全的創(chuàng)建好了,下面就是把 store 跟我們的組件,完全的結(jié)合起來(lái)。這就用到 react-redux 的 connect 模塊。
這個(gè)東西 就是把組件跟 store 連接起來(lái)的模塊。
然后在,App.js加入我們的。store
src/App.js
import React, { Component } from "react" import { BrowserRouter as Router, Route, Link } from "react-router-dom" // 引入 store import { Provider, connect } from "react-redux"; import store from "./redux/store.js" import logo from "./logo.svg" import Plan from "./components/plan.js" import Home from "./components/home.js" import Popup from "./components/pupop.js" import TestRouter from "./components/testrouter.js" import Detail from "./components/detail.js" import "./App.css" import "./components/comment.css" import createHistory from "history/createBrowserHistory" const history = createHistory() class App extends Component { constructor(props) { super(props); } render() { return ( // store的掛載); } } export default App Welcome to React Plan
- 首頁(yè)
- 計(jì)劃表
- 二級(jí)路由
然后在 plan.js連接 store
src/component/plant.js
import React, { Component } from "react" import { connect } from "react-redux"; import store from "../redux/store.js"; // 引入 定義的 action import {show, deletePlan} from "../actions/plan.js"; class Plan extends Component { constructor(props) { super(props); } // 顯示彈出 show () { let b = this.props.planlist.show; store.dispatch(show(!b)); } // 刪除計(jì)劃 delete (id) { store.dispatch(deletePlan(id)); } // js 跳轉(zhuǎn)路由 detail (id) { this.props.history.push(`/detail/${id}`) } render () { return () } } const mapStateToProps = function(store) { return { planlist: store.planlist }; }; // 連接 store,作為 props export default connect(mapStateToProps)(Plan);計(jì)劃表
添加計(jì)劃
{ this.props.planlist.planlist.map((item, index) => { return ( 標(biāo)題 操作 ) }) } {item.title} 刪除
同理下面的 js,都是用這個(gè)模塊連接
src/component/detail.js
import React, { Component } from "react" import { connect } from "react-redux"; import store from "../redux/store.js"; class Detail extends Component { constructor(props) { super(props); // 根據(jù)路由 id 跟 store 做過(guò)濾 let item = props.planlist.planlist.filter((data) => data.id == props.match.params.id) console.log(item) this.state = { plan: item[0] } } render() { return () } } const mapStateToProps = function(store) { return { planlist: store.planlist }; }; // 連接 tore 和組件 export default connect(mapStateToProps)(Detail);計(jì)劃詳情
id: {this.state.plan.id}
標(biāo)題: {this.state.plan.title}
內(nèi)容: {this.state.plan.content}
src/component/popup.js
import React, { Component } from "react" import { connect } from "react-redux"; import store from "../redux/store.js"; import {show, addPlan} from "../actions/plan.js"; class Pupop extends Component{ constructor (props) { super(props) this.state = { id: "", title: "1", content: "1" } } // 取消按鈕操作 close () { let b = this.props.planlist.show; this.setState({ id: "", title: "", content: "" }) store.dispatch(show(!b)); } // 輸入框事件 handleChage (str, e) { this.setState({ id: Math.ceil(Math.random()*10000), [str]: e.target.value }) } // 確認(rèn)操作 conform () { store.dispatch(addPlan(this.state)); this.setState({ id: "", title: "", content: "" }) this.close(); } render() { let self = this; return () } } const mapStateToProps = function(store) { return { planlist: store.planlist }; }; // 連接 store和組件 export default connect(mapStateToProps)(Pupop); X計(jì)劃標(biāo)題
計(jì)劃內(nèi)容
取消 確認(rèn)
完工。github地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83408.html
摘要:通過(guò)聲明式編程模型定義組件,是最強(qiáng)大的核心功能。無(wú)論是的瀏覽器書簽,還是的導(dǎo)航功能,只要是可以使用的地方,就可以使用。二級(jí)路由使用渲染組件屬性狀態(tài)請(qǐng)選擇一個(gè)主題。也許是最佳小實(shí)踐地址,覺(jué)得有幫助的話,請(qǐng)點(diǎn)擊一下,嘿嘿 小前言 這是一個(gè)小小的有關(guān)react的小例子,希望通過(guò)一個(gè)小例子,可以讓新手更好的了解到react、react-router4.0、redux的集中使用方法。 這是基...
摘要:譯者按最近依舊如火如荼相信大家都躍躍欲試我們團(tuán)隊(duì)也開始在領(lǐng)域有所嘗試年應(yīng)該是逐漸走向成熟的一年讓我們一起來(lái)看看國(guó)外的開發(fā)者們都總結(jié)了哪些最佳實(shí)踐年在全世界都有很多關(guān)于新的更新和開發(fā)者大會(huì)的討論關(guān)于去年的重要事件請(qǐng)參考那么年最有趣的問(wèn)題來(lái)了我 譯者按:最近React(web/native)依舊如火如荼,相信大家都躍躍欲試,我們團(tuán)隊(duì)也開始在React領(lǐng)域有所嘗試. 2016年應(yīng)該是Reac...
摘要:首先聲明這篇文章是想說(shuō)明一下最新版本的的新特性帶來(lái)的極大的開發(fā)體驗(yàn)提升而不是如何利用開發(fā)應(yīng)用這個(gè)特性就是對(duì)的支持在的中有說(shuō)明具體可以參考這里在版本之前我們?cè)陂_發(fā)應(yīng)用尤其是在配合一類庫(kù)的時(shí)候經(jīng)常用到諸如之類的封裝而這些函數(shù)其實(shí)都可以用裝飾器的 首先聲明, 這篇文章是想說(shuō)明一下最新版本的 TypeScript(3.0) 的新特性帶來(lái)的極大的 React 開發(fā)體驗(yàn)提升. 而不是如何利用 Ty...
閱讀 1355·2021-11-15 11:45
閱讀 3122·2021-09-27 13:36
閱讀 2866·2019-08-30 15:54
閱讀 984·2019-08-29 12:38
閱讀 2905·2019-08-29 11:22
閱讀 2983·2019-08-26 13:52
閱讀 2024·2019-08-26 13:30
閱讀 584·2019-08-26 10:37