Redux狀態機:
redux管理資料,單獨得js庫,可以和react一起使用,也可以不和react一起使用,
- React專案很小,簡單不復雜,就一兩個人開發,就不需要redux.
- 安裝
npm install --save redux
- 單頁面使用:
- 新建reducer
指定了應用狀態的變化如何回應 actions 并發送到 store 的,記住 actions 只是描述了有事情發生了這一事實,并沒有描述應用如何更新 state,
const counter = (state=0,action={}) =>{
switch(action.type){
case 'INCRMENT':
return state + 1;
case "DECREMENT":
return state -1;
default: return state;
}
}
export default counter;
- 引入redux
import reportWebVitals from './reportWebVitals';
import {createStore} from "redux";
import reducer from "./reducers/counts";
const store = createStore(reducer); 創建store,并傳入reducer
根據已有的 reducer 來創建 store 是非常容易的,在前一個章節中,我們使用 combineReducers() 將多個 reducer 合并成為一個,現在我們將其匯入,并傳遞 createStore(),
改造一下這個組件
Action 是把資料從應用(譯者注:這里之所以不叫 view 是因為這些資料有可能是服務器回應,用戶輸入或其它非 view 的資料 )傳到 store 的有效載荷,它是 store 資料的唯一來源,一般來說你會通過 store.dispatch() 將 action 傳到 store,
const render = () => {
ReactDOM.render(
<App
onIncrment = {() => store.dispatch({type: "INCRMENT"}) }
onDecrement = {() => store.dispatch({type: "DECREMENT"})}
value=https://www.cnblogs.com/historylyt/p/{store.getState()} />,
document.getElementById('root')
);
}
render();
store.subscribe(render);實作監聽
添加一個變化監聽器,每當 dispatch action 的時候就會執行,state 樹中的一部分可能已經變化,你可以在回呼函式里呼叫 getState() 來拿到當前 state,
listener (Function): 每當 dispatch action 的時候都會執行的回呼,state 樹中的一部分可能已經變化,你可以在回呼函式里呼叫 getState() 來拿到當前 state,store 的 reducer 應該是純函式,因此你可能需要對 state 樹中的參考做深度比較來確定它的值是否有變化,
參考網址:http://cn.redux.js.org/docs/basics/Store.html
5.react-redux資料傳遞到component
npm install react-redux
import {createStore} from "redux";
// import reducer from "./reducers/counts";
import rootReducer from "./reducers";
import {incrment,decrment} from "./actions";
import {Provider} from "react-redux";
const store = createStore(rootReducer);
//store.subscribe(() => console.log("State updated!",store.getState()));
ReactDOM.render(
<Provider store={store}>
Provider組件作為做上層組件,需要將store作為引數注入組件中,此后在子組件中都可以訪問到store這個物件;connect方法接受兩個引數:mapStateToProps,actionCreators,并回傳處理后的組件,其中mapStateToProps可以將對應的state作為prop注入對應的子組件,actionCreator可以將對應的actioncreator作為prop注入對應的子組件
<App/>
</Provider>,
document.getElementById('root')
);
Reducdrs:
import {combineReducers} from "redux";
import counter from './counts';
import user from "./user";
//combineReducers Redux 提供了一個combineReducers方法,用于 Reducer 的拆分,你只要定義各個子 Reducer 函式,然后用這個方法,將它們合成一個大的 Reducer,
const rootReducer = combineReducers({
counter,
user
});
export default rootReducer
下層:
import {connect} from "react-redux";
獲取到:
<h1 className="jumbotron-heading text-center">
{this.props.counter}
</h1>
mapStateToProps可以將對應的state作為prop注入對應的子組件
const mapStateToProps = (state) => {
console.log("state",state);
return {
counter: state.counter
}
}
//connect高階組件 React-Redux提供一個connect方法能夠讓你把組件和store連接起來,
export default connect(mapStateToProps)(App);
- Dispatch和Action
Component子組件可以用dispatch呼叫action,并傳遞相對應得單個引數,以及物件:
Constructor里列印:
console.log("props",props);發現有dispatch這個方法
定義好action方法里得傳遞引數:
export const incrment = (name) => {
return {
type: type.INCRMENT,
name
}
}
export const decrment = () => {
return {
type: type.DECREMENT
}
}
Component呼叫dispatch,并傳遞對應得單個引數,多個引數
<p className="text-center">
<button onClick={() => dispatch(incrment({name:"小豬",id:2}))} className="btn btn-primary my-2">新增</button>
<button onClick={() => dispatch(decrment())} className="btn btn-danger my-2">減少</button>
</p>
設定reducers得時候列印一下:
case 'INCRMENT':
console.log("action",action); 列印action
return state + 1;
- mapDispatchToProps(教程作者提示,這個不太友好)
const mapDispatchToProps = (dispatch) => {
return {
add:(name) => { dispatch(incrment(name))}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(App);
//使用這個mapDispatchToProps,就不能從props里獲取到dispatch了,可以拿到自定義得add方法,進行使用
const {add} = this.props;
<button onClick={() => add("殺盡天下有情人")} className="btn btn-primary my-2">新增</button>
- bindActionCreators比上一種簡潔一些:
// const mapDispatchToProps = (dispatch) => {
// return {
// add: bindActionCreators(incrment,dispatch)
// }
// }
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({incrment},dispatch)
}
export default connect(mapStateToProps,mapDispatchToProps)(App);
還可以:
export default connect(mapStateToProps,{incrment,decrment})(App);
- 中間件:
Logger
//中間件:
const logger = store => next => action => {
console.log("dispatching",action);
let result = next(action);
console.log('next state',store.getState());
return result;
}
//createStore (1引數:reducer
// ,2引數:initialState初始時的 state
// ,3引數:enhancer 是一個組合 store creator 的高階函式,回傳一個新的強化過的 store creator,這與 middleware 相似,它也允許你通過復合函式改變 store 介面,
// )
const store = createStore(rootReducer,{},applyMiddleware(logger));
- 異步yarn add redux-thunk
發送ajax請求:
yarn add axios
axios.get("https://randomuser.me/api123")
.then(res => {
console.log(res.data.results);
dispatch(fetch_user(res.data.results[0]));
})
.catch(error => {
//console.log(error)
dispatch(fetch_user_failure(error.response.data));
})
11.redux-promise-middleware
用來處理異步的中間件為 redux-promise-middleware ,相比較 redux-promise 它保留了樂觀更新的能力,在啟用它之后,我們可以觸發一個 payload 屬性為 promise 物件的 action
const foo = () => ({
type: 'FOO',
payload: new Promise()
})
異步操作action得3個狀態,PEDING加載,FULFILLED成功,REJECATED失敗
switch (action.type) {
case 'MY_ACTION_TYPE_PENDING':
return {...state, myActionLoading: true}
case 'MY_ACTION_TYPE_FULFILLED':
return {...state, xxx, myActionLoading: false}
case 'MY_ACTION_TYPE_REJECTED':
return {...state, myActionLoading: false}
}
redux-promise-middleware 處理程序,當有異步事件開始或者狀態改變時,我們除了觸發原來的事件外,也觸發一個特殊事件的 action,它攜帶當前事件的 type 和 狀態 作為引數, 當接收到這個事件后我們把這個 reducer 對應的 type 的狀態改為引數的的狀態,這樣我們就可以自動的更新每一個 action 目前的狀態值了,
12.打包:
npm build 或者 npm run build
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/274379.html
標籤:JavaScript
下一篇:前端面試題0409
