个人Blog,欢迎踩坑
npm install --save redux
/**
* 包含n个reducer函数的模块
*/
import {INCREMENT,DECREMENT} from './action-types';
export function counter(state = 0,action){
switch(action.type){
case INCREMENT:
return state + action.data;
case DECREMENT:
return state - action.data;
default:
return state;
}
}
/**
* 包含所有action type的常量字符
*/
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
/**
* 包含所有actions creator
*/
import {INCREMENT,DECREMENT} from './action-types';
//增加
export const increment = (val) => ({type:INCREMENT,data:val});
//减少
export const decrement = (val) => ({type:DECREMENT,data:val});
import {createStore} from 'redux';
import {counter} from './reducers';
const store = createStore(counter);
console.log(store);
export default store;
import store from './redux/store'
function render(){
//注意,要将store对象传给组件
ReactDOM.render(, document.getElementById('root'));
}
render();
import React,{Component} from 'react';
import './App.css';
import * as actions from '../../redux/actions';
export default class App extends Component{
increment = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//2. 分发事件:触发发布,更新状态
//dispatch(action)中的action对应reducers定义的counter函数的action参数
this.props.store.dispatch(actions.increment(val));
}
incrementIfOdd = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//获取状态的初始值
const count = this.props.store.getState();
if(count % 2 === 1){
//更新状态
this.props.store.dispatch(actions.increment(val));
}
}
decrement = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//更新状态
this.props.store.dispatch(actions.decrement(val));
}
incrementAsync = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
setTimeout(() => {
//更新状态
this.props.store.dispatch(actions.increment(val));
}, 1000);
}
render(){
//1. 读取状态的值
const count = this.props.store.getState();
return (
click {count} times
);
}
}
//一旦状态更新,重新渲染组件
store.subscribe(render);
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/app/App';
import store from './redux/store'
function render(){
ReactDOM.render(, document.getElementById('root'));
}
render();
//一旦状态更新,重新渲染组件
store.subscribe(render);
// 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: https://bit.ly/CRA-PWA
npm install --save react-redux
,简化在react中redux的语法import {Provider} from 'react-redux';
//将store对象的管理权交给react-redux
ReactDOM.render(
, document.getElementById('root'));
npm install prop-types
import React,{Component} from 'react';
//1. 引入propTypes
import PropTypes from 'prop-types';
import './App.css';
export default class App extends Component{
//2. 将store对象提供的数据都定义为属性
static propTypes = {
count : PropTypes.number.isRequired,
increment : PropTypes.func.isRequired,
decrement : PropTypes.func.isRequired
}
increment = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
// debugger
//更新状态
this.props.increment(val);
}
incrementIfOdd = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//获取状态的初始值
const count = this.props.store.getState();
if(count % 2 === 1){
//更新状态
this.props.increment(val);
}
}
decrement = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//更新状态
this.props.decrement(val);
}
incrementAsync = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
setTimeout(() => {
//更新状态
this.props.increment(val);
}, 1000);
}
render(){
const {count} = this.props;
return (
click {count} times
);
}
}
import React,{Component} from 'react';
import PropTypes from 'prop-types';
//1. 引入connect 连接App和redux
import {connect} from 'react-redux';
import './App.css';
//3. 引入redux中App需要的函数
import {increment,decrement} from '../../redux/actions'
//2. 不再直接暴露App
class App extends Component{
static propTypes = {
count : PropTypes.number.isRequired,
increment : PropTypes.func.isRequired,
decrement : PropTypes.func.isRequired
}
increment = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
// debugger
//更新状态
this.props.increment(val);
}
incrementIfOdd = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//获取状态的初始值
const {count} = this.props;
if(count % 2 === 1){
//更新状态
this.props.increment(val);
}
}
decrement = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//更新状态
this.props.decrement(val);
}
incrementAsync = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
setTimeout(() => {
//更新状态
this.props.increment(val);
}, 1000);
}
render(){
const {count} = this.props;
return (
click {count} times
);
}
}
//4. 暴露一个connect包装后的App,connect(param1,param2),param1是一个回调函数,用来传递数值属性,param2是一个对象,用来传递函数属性,将redux中的函数increment,decrement传给App,由react-redux分发///(dispatch)给redux做状态更新
//param2 : {increment:increment,decrement:decrement}其中key对应App中属性的名称,value对应redux中actions的函数名称
export default connect(
state => ({count:state}),
{increment,decrement}
)(App);
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import './counter.css';
export default class Counter extends Component{
static propTypes = {
count : PropTypes.number.isRequired,
increment : PropTypes.func.isRequired,
decrement : PropTypes.func.isRequired
}
increment = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
// debugger
//更新状态
this.props.increment(val);
}
incrementIfOdd = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//获取状态的初始值
const {count} = this.props;
if(count % 2 === 1){
//更新状态
this.props.increment(val);
}
}
decrement = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//更新状态
this.props.decrement(val);
}
incrementAsync = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
setTimeout(() => {
//更新状态
this.props.increment(val);
}, 1000);
}
render(){
const {count} = this.props;
return (
click {count} times
);
}
}
import React from 'react';
import {connect} from 'react-redux';
import Counter from '../../components/counter/counter';
import {increment,decrement} from '../../redux/actions'
export default connect(
state => ({count:state}),
{increment,decrement}
)(Counter);
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import './index.css';
//1. 主要是app.jsx文件的位置修改
import App from './containers/app/app';
import store from './redux/store'
//将store的使用权都交给Provider
ReactDOM.render(
, 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: https://bit.ly/CRA-PWA
npm install --save redux-thunk
//1. 引入应用中间件的函数applyMiddleware
import {createStore,applyMiddleware} from 'redux';
//2. 引入异步中间件
import thunk from 'redux-thunk';
import {counter} from './reducers';
const store = createStore(
counter,
applyMiddleware(thunk)//3. 声明应用异步的中间件
);
console.log(store);
export default store;
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import './counter.css';
export default class Counter extends Component{
static propTypes = {
count : PropTypes.number.isRequired,
increment : PropTypes.func.isRequired,
decrement : PropTypes.func.isRequired,
//1. 定义一个异步的函数属性,由react-redux从actions中传过来
incrementAsync : PropTypes.func.isRequired,
}
increment = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
// debugger
//更新状态
this.props.increment(val);
}
incrementIfOdd = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//获取状态的初始值
const {count} = this.props;
if(count % 2 === 1){
//更新状态
this.props.increment(val);
}
}
decrement = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
//更新状态
this.props.decrement(val);
}
incrementAsync = () => {
//获取下拉框的值:非受控组件
const val = this.select.value*1;
// setTimeout(() => {
// //更新状态
// this.props.increment(val);
// }, 1000);
//2. 将异步行为放到redux中处理
this.props.incrementAsync(val);
}
render(){
const {count} = this.props;
return (
click {count} times
);
}
}
import React from 'react';
import {connect} from 'react-redux';
import Counter from '../../components/counter/counter';
//1. 引入异步的action
import {increment,decrement,incrementAsync} from '../../redux/actions'
export default connect(
state => ({count:state}),
{increment,decrement,incrementAsync}//2. 将异步的action传到ui组件中
)(Counter);
/**
* 包含所有actions creator
*/
import {INCREMENT,DECREMENT} from './action-types';
//增加,同步action返回的是一个对象
export const increment = (val) => ({type:INCREMENT,data:val});
//减少,同步action返回的是一个对象
export const decrement = (val) => ({type:DECREMENT,data:val});
//1. 异步action返回的是函数
export const incrementAsync = (val) => {
return dispatch => {
//异步代码
setTimeout(() => {
//1s后才分发一个同步的action(这里是增加的功能,所以直接调用增加的同步action即可,如果需要的功能没有,还需自定义功能的一个同步action)
dispatch(increment(val));
}, 1000);
}
};
//1. 从redux引入整合reducer的函数
import { combineReducers } from 'redux'
import { ADD_COMMENT, DELETE_COMMENT, INIT_COMMENTS, INCREMENT, DECREMENT } from './action-type';
//2. reducer不要分别暴露
function comments(state = [], action) {
switch (action.type) {
case ADD_COMMENT:
return [action.data, ...state];
case DELETE_COMMENT:
console.log(action.data);
return state.filter((comment, index) => action.data !== index);
case INIT_COMMENTS:
return action.data;
default:
return state;
}
}
function counter(state = 0, action) {
switch (action.type) {
case INCREMENT:
return state + action.data;
case DECREMENT:
return state - action.data;
default:
return state;
}
}
//3. 整合reducer,然后暴露
export default combineReducers({
comments,
counter
});
import React from 'react';
import { createStore, applyMiddleware } from 'redux';
//1. 引入整合后的reducers
import reducers from './reducers';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension'
//2. 创建store对象传入reducers
const store = createStore(reducers, composeWithDevTools(applyMiddleware(thunk)));
export default store;
//3. 此时 redux向外暴露的state是一个对象(即getState()方法得到的是一个对象)
// {counter:2,comments:[]}
import React,{Component} from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import './app.css';
import CommentAdd from '../../component/comment-add/comment-add'
import CommentList from '../../component/comment-list/comment-list'
import {addComment,handleDelete,getComments} from '../../redux/actions';
class App extends Component{
static propTypes = {
comments:PropTypes.array.isRequired,
addComment:PropTypes.func.isRequired,
handleDelete:PropTypes.func.isRequired,
}
componentDidMount(){
//初始化comments
this.props.getComments();
}
render(){
const {comments,addComment,handleDelete} = this.props;
return (
请发表对React的评论
);
}
}
export default connect(
//state是一个对象,对应reducers.js中的每个reducer
state => ({comments:state.comments}),
{addComment,handleDelete,getComments}
)(App);