Redux基礎知識

Redux是什麼

  • Redux專注於狀態管理,和react解耦 單
  • 一狀態,單向數據流
  • 核心概念:store,state,action,reducer
import { createStore } from 'redux'

const store = createStore(counter) // 創建倉庫
store.subscribe(listener) // 訂閱
store.dispatch({type: 'add'}) // 派發事件
store.dispatch({type: 'del'})

function counter (state=0, action) {
	switch (action.type) {
		case 'add':
			return state+1
		case 'del':
			return state-1
		default:
			return 10
	}
}

function listener () {
	const current = store.getState()
	console.log(current)
}

Redux狀態管理,使用React-redux

yarn add react-redux

React-redux提供Provide和connect兩個接口接口來鏈接

React-redux具體使用

  • Provide組件在應用最外層,傳入store即可,只用一次
  • Connect負責從外部獲取組件需要的參數
  • Connect可以用裝飾器的方式來寫

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import thunk from 'redux-thunk'
import {createStore, applyMiddleware, compose} from 'redux'
import App from './App.js'
import { Provider } from 'react-redux'
import { counter } from './index.redux.js'

const reduxDevtools = window.devToolsExtension ? window.devToolsExtension() : () => {}
const store = createStore(counter, compose(
	applyMiddleware(thunk),
	reduxDevtools
))

ReactDOM.render(
	(<Provider store={store}>
		<App />
	</Provider>)
	, document.getElementById('root')
)


App.js

import React from 'react'
import { connect } from 'react-redux'
import { addGun, delGun, addGunAsync } from './index.redux.js'

class App extends React.Component{
	render () {
		return (
			<div>
				<h1>現在有激情{this.props.num}</h1>
				<button onClick={() => this.props.addGun()}>申請武器</button>
				<button onClick={() => this.props.delGun()}>放棄武器</button>
				<button onClick={() => this.props.addGunAsync()}>拖兩天再給</button>
			</div>
		)
	}
}

const mapStatetoProps = (state) => {
	return {
		num: state
	}
}

const actionCreators = { addGun, delGun, addGunAsync }

App = connect(mapStatetoProps, actionCreators)(App)

export default App

index.redux.js

const ADD = 'add'
const DEL= 'del'
// reducer
export  function counter (state=0, action) {
	switch (action.type) {
		case ADD:
			return state+1
		case DEL:
			return state-1
		default:
			return 10
	}
}

export function addGun () {
	return {
		type: ADD
	}
}

export function delGun () {
	return {
		type: DEL
	}
}

// 異步提交
export function addGunAsync () {
	return dispatch => {
		setTimeout(() => {
			dispatch(addGun())
		}, 2000)
	}
} 

使用裝飾器優化connect代碼

yarn eject 彈出個性化配置
yarn add @babel/plugin-proposal-decorators --dev 插件

Package.json裏babel加上plugins配置
["@babel/plugin-proposal-decorators", { “legacy”: true }]

"babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }]
    ]
  }

App.js

// import React from 'react';
// import logo from './logo.svg';
// import './App.css';

// function App() {
//   return (
//     <div className="App">
//       <header className="App-header">
//         <img src={logo} className="App-logo" alt="logo" />
//         <p>
//           Edit <code>src/App.js</code> and save to reload.
//         </p>
//         <a
//           className="App-link"
//           href="https://reactjs.org"
//           target="_blank"
//           rel="noopener noreferrer"
//         >
//           Learn React
//         </a>
//       </header>
//     </div>
//   );
// }

// export default App;

// import React from 'react';
// import {Button} from 'antd-mobile'
// import 'antd-mobile/dist/antd-mobile.css'
// import { List } from 'antd-mobile';
// const Item = List.Item;
// class App extends React.Component{
// 	render () {
// 		let boss = '李雲龍'
// 		return (
// 			<div>
// 				<Yiying big='張大喵'></Yiying>
// 				<Qibinglian big='孫德勝'></Qibinglian>
// 				<h2>獨立團,團長{boss}</h2>
// 			</div>
// 		)
// 	}
// }

// function Qibinglian (props) {
// 	return <h2>騎兵連連長,{props.big}衝啊</h2>
// }

// class Yiying extends React.Component{
// 	constructor(props) {
// 	    super(props)
// 		this.state = {
// 			solders: ['虎子', '柱子', '王根生']
// 		}
// 		// this.addSolder = this.addSolder.bind(this)
// 	}
// 	componentWillMount () {
// 		console.log('組件馬上就要加載了')
// 	}
// 	addSolder () {
// 		console.log('add solder')
// 		this.setState({
// 			solders: [...this.state.solders, '牛愛花' + Math.random()]
// 		})
// 	}
// 	componentDidMount () {
// 		console.log('組件加載完畢')
// 	}
// 	render () {
// 		console.log('組件正在加載了')
// 		return (
// 			<div>
// 				<h2>一營營長,{this.props.big}</h2>
// 				<Button type="primary" onClick={() => this.addSolder()}>新兵入伍</Button>
// 				<List renderHeader={() => '士兵列表'} className="my-list">
// 					{
// 						this.state.solders.map((item) => {
// 							return  <Item arrow={'horizontal'} key={item}>{item}</Item>
      
// 						})
// 					}
// 				</List>
// 			</div>
// 		)
// 	}
// }

// export default App

import React from 'react'
import { connect } from 'react-redux'
import { addGun, delGun, addGunAsync } from './index.redux.js'

const actionCreators = { addGun, delGun, addGunAsync }

// App = connect(mapStatetoProps, actionCreators)(App)

@connect(
	state => state.num, // 你要state什麼屬性放到props裏
	{ addGun, delGun, addGunAsync } // 你要什麼方法,放到propsli ,自動dispatch
)
class App extends React.Component{
	render () {
		return (
			<div>
				<h1>現在有激情{this.props.num}</h1>
				<button onClick={() => this.props.addGun()}>申請武器</button>
				<button onClick={() => this.props.delGun()}>放棄武器</button>
				<button onClick={() => this.props.addGunAsync()}>拖兩天再給</button>
			</div>
		)
	}
}

export default App

後續進階:

  • 什麼數據應該放在React裏
  • Redux管理ajax
  • Redux管理聊天數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章