// Redux
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {createStore, combineReducers, applyMiddleware, bindActionCreators} from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';
function counterUpReducer (state = 0, action) {
switch (action.type) {
case 'COUNTER_UP': return state + action.value;
default: return state;
}
}
function counterUpAction (value) {
return {
type: 'COUNTER_UP'
, value: value
};
}
function asyncCounterUpAction (value, setState) {
return (dispatch) => {
setTimeout(function () {
dispatch(counterUpAction(value));
}, 1000);
};
}
function counterDownReducer (state = 0, action) {
switch (action.type) {
case 'COUNTER_DOWN': return state + action.value;
default: return state;
}
}
function counterDownAction (value) {
return {
type: 'COUNTER_DOWN'
, value: value
};
}
function asyncCounterDownAction (value) {
return (dispatch) => {
setTimeout(function () {
dispatch(counterDownAction(value));
}, 1000);
};
}
const reducers = combineReducers({
counterUp: counterUpReducer
, counterDown: counterDownReducer
});
const initialState = {
counterUp: 0
, counterDown: 0
};
const store = createStore(reducers, initialState, applyMiddleware(logger(), thunk));
store.subscribe(() => {console.log(store.getState());});
const actionCreators = {
boundCounterUpAction: counterUpAction
, boundCounterDownAction: counterDownAction
};
const boundActions = bindActionCreators(actionCreators, store.dispatch);
class App extends Component {
render () {
return (
<CounterBlock
counterUpAction={counterUpAction}
counterDownAction={counterDownAction}
boundActions={boundActions}
asyncCounterUpAction={asyncCounterUpAction}
asyncCounterDownAction={asyncCounterDownAction}
/>
);
}
}
class CounterBlock extends Component {
render () {
return (
<Counter
counterUpAction={this.props.counterUpAction}
counterDownAction={this.props.counterDownAction}
boundActions={this.props.boundActions}
asyncCounterUpAction={this.props.asyncCounterUpAction}
asyncCounterDownAction={this.props.asyncCounterDownAction}
/>
);
}
}
class Counter extends Component {
constructor (props) {
super(props);
this.state = store.getState();
}
render () {
return (
<div id="counter">
<span id="counter-up">{this.state.counterUp}</span>
{' '}
<span id="up" onClick={this.handleUpClick.bind(this)}>Вверх</span>
{' '}
<span id="up-bound" onClick={this.handleBoundUpClick.bind(this)}>Вверх связанный</span>
{' '}
<span id="up-async" onClick={this.handleAsyncUpClick.bind(this)}>Вверх асинхронный</span>
<br /><br />
<span id="counter-down">{this.state.counterDown}</span>
{' '}
<span id="down" onClick={this.handleDownClick.bind(this)}>Вниз</span>
{' '}
<span id="down-bound" onClick={this.handleBoundDownClick.bind(this)}>Вниз связанный</span>
{' '}
<span id="down-async" onClick={this.handleAsyncDownClick.bind(this)}>Вниз асинхронный</span>
</div>
);
}
handleUpClick () {
store.dispatch(this.props.counterUpAction(1));
this.setState(Object.assign({}, this.state, {counterUp: store.getState().counterUp}));
}
handleDownClick () {
store.dispatch(this.props.counterDownAction(-1));
this.setState(Object.assign({}, this.state, {counterDown: store.getState().counterDown}));
}
handleBoundUpClick () {
this.props.boundActions.boundCounterUpAction(1);
this.setState(Object.assign({}, this.state, {counterUp: store.getState().counterUp}));
}
handleBoundDownClick () {
this.props.boundActions.boundCounterDownAction(-1);
this.setState(Object.assign({}, this.state, {counterDown: store.getState().counterDown}));
}
handleAsyncUpClick () {
store.dispatch(this.props.asyncCounterUpAction(1));
setTimeout(() => {
this.setState(Object.assign({}, this.state, {counterUp: store.getState().counterUp}));
}, 2000);
}
handleAsyncDownClick () {
store.dispatch(this.props.asyncCounterDownAction(-1));
setTimeout(() => {
this.setState(Object.assign({}, this.state, {counterDown: store.getState().counterDown}));
}, 2000);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
Комментариев нет:
Отправить комментарий