https://github.com/chunhuigao/react-redux-thunk
创建react工程
create-react-app study-redux
复制代码
启动react服务
安装redux
npm install redux
npm install react-redux
npm install redux-thunk
复制代码
我的工程目录
删除无用的代码
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';class App extends Component {render() {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><aclassName="App-link"href="https://reactjs.org"target="_blank"rel="noopener noreferrer">Learn React</a></header> */}</div>);}
}export default App;复制代码
创建第一个组件
import React, { Component } from 'react'class Hello extends Component {render() {return (<div><h2>学习redux</h2></div>)}
}
export default Hello
复制代码
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Hello from './component/hello/hello.js'
class App extends Component {render() {return (<div className="App"><Hello /></div>);}
}export default App;
复制代码
添加第一个事件
import React, { Component } from 'react'
import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {return (<div><h2>{this.state.title}</h2><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}
export default Hello
复制代码
开始使用redux
index.js引用一下内容
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';import { Provider } from 'react-redux' //新引入
import {createStore} from 'redux' //新引入
import rootReducer from './rootReducer.js' //新引入const store = createStore(rootReducer)
ReactDOM.render(
<Provider store={store}><App />
</Provider>
, document.getElementById('root'));// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();复制代码
创建rootReducer
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
const rootReducer = combineReducers({helloReducer
})
export default rootReducer
复制代码
创建helloReducer.js
const initState = {name:'hello,redux'
}
export default (state=initState,action) => {switch (action.type) {case 'CHANGE_NAME':return {...state,name:action.text}default:return state;}
}
复制代码
数据绑定到组件
import React, { Component } from 'react'//引用connect
import {connect} from 'react-redux'import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {
//此处打印this.props应该可以看到helloProp这个对象了,证明数据已经挂在到组件紫红console.log(this.props)let {prop} = this.propsreturn (<div><h2>{this.state.title}</h2><h3>我是来自redux数据{prop.name}</h3><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}//mapStateToProps是connect一个参数, 作用到将store中的数据作为 props 绑定到组件上
const mapStateToProps = (state, ownProps) => {return {helloProp: state.helloReducer//helloReducer是在rootReducer中的名}
}
//通过connect高阶函数绑定数据
export default connect(mapStateToProps)(Hello)
复制代码
创建helloAction.js
const helloAction = {changeName:(text)=>({type:"CHANGE_NAME",text:text,mate:'用于改变helloReducer中name值'})
}
export default helloAction
复制代码
将action绑定到组件
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
//引入helloAction
import helloAction from './helloAction.js'
import './hello.css'class Hello extends Component {constructor(props){super(props)this.state = {title:'学习redux'}}changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)this.setState({title:title})}render() {//此处打印,应该可以看到actionsconsole.log(this.props)let {prop} = this.propsreturn (<div><h2>{this.state.title}</h2><h3>我是来自redux数据{prop.name}</h3><button className="btn" onClick={()=>{this.changeTitle()}}>点击我改变标题</button></div>)}
}const mapStateToProps = (state, ownProps) => {return {prop: state.helloReducer}
}//使用mapDispatchToProps绑定helloAction
const mapDispatchToProps = (dispatch, ownProps) => {return {actions:bindActionCreators(helloAction,dispatch)}
}
//将mapDispatchToProps作为参数给connect
export default connect(mapStateToProps,mapDispatchToProps)(Hello)
复制代码
changeTitle(){let title = '学习redux' + Math.ceil(Math.random()*100)// this.setState({// title:title// })let {actions} = this.propsactions.changeName(title)}
复制代码
创建other组件
import React, { Component } from 'react';
import Hello from './component/hello/hello.js'
import Other from './component/other/other.js'
import './App.css';class App extends Component {render() {return (<div className="App"><Hello /><Other /></div>);}
}export default App;复制代码
other具体代码
import React, { Component } from 'react'
import {bindActionCreators} from 'redux'
import {connect} from 'react-redux'
import helloAction from '../hello/helloAction.js'class Other extends Component {changeName(){let {helloAction} = this.props;let text = 'other' + (Math.random() *100)helloAction.changeName(text)}render() {let {otherProp} = this.propsconsole.log(this.props)return (<div><h3>我是其他组件</h3><button className="btn" onClick={()=>{this.changeName()}}>我是其他组件的按钮</button></div>)}
}const mapStateToProps = (state, ownProps) => {return {otherProp: state.helloReducer}
}
const mapDispatchToProps = (dispatch, ownProps) => {return {helloAction:bindActionCreators(helloAction,dispatch)}
}
export default connect(mapStateToProps,mapDispatchToProps)(Other)
复制代码
组件上绑定多个数据
const initState = {title:'我是otherReducer数据'
}export default (state=initState,action) => {switch (action.type) {case "CHANGE_TITLE":return {...state,title:action.text}default:return state}
}
复制代码
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
import otherReducer from './component/other/otherReducer.js'
const rootReducer = combineReducers({helloReducer,otherReducer
})
export default rootReducer
复制代码
const mapStateToProps = (state, ownProps) => {return {helloProp: state.helloReducer,otherProp: state.otherReducer}
}
复制代码
render() {let {helloProp,otherProp} = this.propsconsole.log(this.props)return (<div><h3>我是其他组件</h3><button className="btn" onClick={()=>{this.changeName()}}>我是其他组件的按钮</button><div>{otherProp.title}</div></div>)}
复制代码
redux异步操作
//注释import {createStore} from 'redux'
//新增
import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'//注释 const store = createStore(rootReducer)
//新增
const store = createStore(rootReducer,applyMiddleware(thunk))
复制代码
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'
import exampleAction from './exampleAction.js'
class Example extends Component {asyncFn(){let {exampleAction} = this.propsexampleAction.asyncThing()console.log(this.props)}render() {let {exampleProp} = this.propsreturn (<div><h3>异步操作</h3><h4>{exampleProp.text}</h4><button className='btn' onClick={()=>{this.asyncFn()}}>我要进行异步操作</button></div>)}
}
const mapStateToProps = (state, ownProps) => {return {exampleProp: state.exampleReducer}
}
const mapDispatchToProps = (dispatch, ownProps) => {return {exampleAction:bindActionCreators(exampleAction,dispatch)}
}
export default connect(mapStateToProps,mapDispatchToProps)(Example)
复制代码
const initState={text:'我是用来测试异步操作的',sign:null
}
export default (state=initState,action) =>{console.log(action)switch (action.type) {case 'SUCCESS':return {...state,text:action.text,sign:'success'}case 'ERROR':return {...state,text:action.text,sign:'error'}default:return state}
}
复制代码
const exampleAction = {asyncThing:()=>{return (dispatch, getState) =>{// fetch('https://hacker-news.firebaseio.com/v0/jobstories.json')// .then(res => {// dispatch(exampleAction.asyncSuccess('我是成功回调')) // }).catch(e => {// dispatch(exampleAction.asyncError('我是成功回调')) // });setTimeout(() => {let sign = Math.random() >= 0.5 ? true : false;console.log(sign)sign ? dispatch(exampleAction.asyncSuccess('我是成功数据')) : dispatch(exampleAction.asyncError('我是失败数据')) }, 2000);}},asyncSuccess:(text)=>({type:'SUCCESS',text:text,mate:'异步成功操作'}),asyncError:(text)=>({type:'ERROR',text:text,mate:'异步成功操作'})
}
export default exampleAction
复制代码
import {combineReducers} from 'redux'
import helloReducer from './component/hello/helloReducer.js'
import otherReducer from './component/other/otherReducer.js'
import exampleReducer from './component/example/exampleReducer.js'
const rootReducer = combineReducers({helloReducer,otherReducer,exampleReducer
})
export default rootReducer
复制代码