簡單來說applyMiddleware是使action中能做更多的事情,如同去賦予執行action有能力在中間去多執行function,不同只是傳遞資料參數,thunk則在中間扮演著處理非同步問題。

Thunk應用增加延遲2秒

const { createStore, applyMiddleware } = Redux;
const { Provider, connect } = ReactRedux
const thunk = ReduxThunk.default
const Increment = () =>{
  return function (dispatch){
    setTimeout(()=>{
      dispatch({type: 'INCREMENT'})
    },2000)
  }
  // return {
  //     type: 'INCREMENT'
  // }
}
class Counter extends React.Component {
  render() {
    console.log(this.props);
    return (
      <div>
        <h2>Counter</h2>
        <div>
          <button onClick={this.props.decrement}>-</button>
          <span>{this.props.count}</span>
          <button onClick={this.props.increment}>+</button>
        </div>
      </div>
    )
  }
}
const actionsCreators = (dispatch)=> {
  return{
    increment: () => {
      //store.dispatch({ type: 'INCREMENT' });
      dispatch(Increment())
    },
    decrement : () => {
      dispatch({ type: 'DECREMENT' });
    }
  }
}
function mapStateToProps(state) {
  console.log(state);

  return {
    count: state.count
  };
}

const Concounter = connect(mapStateToProps,actionsCreators)(Counter);

const initialState = {
  count: 0
};

function reducer(state = initialState, action) {
  switch(action.type) {
    case 'INCREMENT':
      return {
        count: state.count + 1
      };
    case 'DECREMENT':
      return {
        count: state.count - 1
      };
    default:
      return state;
  }
}

const store = createStore(reducer,window.devToolsExtension ? window.devToolsExtension() : undefined ,applyMiddleware(thunk));

const App = () => (
  <Provider store={store}>
    <Concounter/>
  </Provider>
);

ReactDOM.render(<App />, document.getElementById('root'));

DEMO 1

Thunk axios AJAX load資料範例展示

const { createStore, applyMiddleware } = Redux;
const { Provider, connect } = ReactRedux
const thunk = ReduxThunk.default

const loadLorem = () => {
  return (dispatch) => {
    // console.log("****")
    axios.get("https://baconipsum.com/api/?type=all-meat&sentences=1&start-with-lorem=0")
      .then(response => {
        // console.log(response.data)
        dispatch({type: 'CHANGE_SENTENCE', sentence: response.data[0]})
      }
    )
  }
}

const defaultState = {
  sentence: "Waiting for load"
}

const mainReducer = (prevState = defaultState, action) => {
  if (action.type === "CHANGE_SENTENCE") {
    return {...prevState, sentence: action.sentence}
  }
  else if (action.type === "TEST") {
    return {...prevState, sentence: action.value}
  }
  else {
    return prevState
  }
}

const MessageBox = (props) => {
  return <div>{ props.message }</div>
}

const mapStateToProps = state => state
const actionsCreators = {
  loadLorem: loadLorem,
  testAction: () => ({type: 'TEST', value: 'VALUE'})
}

const store = createStore(mainReducer, applyMiddleware(thunk))
// const store = createStore(mainReducer)

const App = (props) => {
  return <div>
    <button onClick={props.loadLorem}>LOAD_LOREM</button>
    <button onClick={props.testAction}>TEST</button>
    <MessageBox message={props.sentence}/>
  </div>
}

const AppConnected = connect(mapStateToProps, actionsCreators)(App)
// const AppConnected = connect(mapStateToProps, mapDispatchToProps)(App)

ReactDOM.render(<Provider store={store}><AppConnected sentence="Lorem" /></Provider>, document.getElementById('root'));

DEMO 2

您也可能喜歡這些文章

Copyright © 2018 ucamc