markdown 介绍一个React y Redux

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 介绍一个React y Redux相关的知识,希望对你有一定的参考价值。

# Paquetes básicos
```PowerShell
npm install redux react-redux redux-axios-middleware react-router-redux redux-thunk --save
```

# Concepts

## Actions
- An object with a ```type: string``` property and any extra data that can be used by the store as income for the middleware, and then for the reducers.

## Reducer
- A function that takes an incoming state and an incoming action, and returns an outcoming state.
- Contains a switch statement to return different result depending on the action.

## Store
- Configure the reducers and the middleware that alter the data

## Thunk
- A function returned by another function with the intention to defer the execution for later. 

## Middleware
- Extra functionality used by the store to perform some extra operations over the action before send the action to the reducer. i.e. axiosMiddleware. 
- Sometimes, in order to this extra functionality works, some specific payload must be sent in the action. 
- The middleware can perform changes to the payload synchronically or asynchonically, so maybe the reducer receives the action before the payload was updated by the middleware. If the task is asynchonous, the middleware can also dispatch a new action once the first action is complete.


# Configuration
1. Install the packages
2. Create a folder called ```redux``` below the root folder
3. Create the main store. Let's call this file ```configureStore.js```, and inside of it let's add the following code:

  ```JavaScript
  import { createStore, applyMiddleware } from "redux";
  import thunk from "redux-thunk";
  import reducers from "./reducers";
  import axios from "axios";
  import { axiosMiddleware } from "redux-axios-middleware";
  
  const client = axios.create({ //all axios can be used, shown in axios documentation
      //baseURL: restUrl,
      //responseType: 'json'
  });
  
  function configureStore(initialState = {}) {
      return createStore(reducers,
          initialState,
          applyMiddleware(thunk, axiosMiddleware(client))
      );
  }

  export default configureStore;
  ```
4. Create the file ```/redux/actions/speakers.js``` with the action dispatcher methods:

  ```JavaScript
  export const SPEAKER_LOAD = 'SPEAKER_LOAD';
  export const SPEAKER_LOAD_SUCCESS = 'SPEAKER_LOAD_SUCCESS';
  export const SPEAKER_LOAD_FAIL = 'SPEAKER_LOAD_FAIL';
  
  export function speakersFetchData() {
      return {
          type: SPEAKER_LOAD,
          payload: {
              request: {
                  url: '/data/speakers.json'
              }
          }
      };
  }
  ``` 

5. Create the reducer ```/redux/reducers/speakers.js```:

  ```JavaScript
  import { SPEAKER_LOAD, SPEAKER_LOAD_SUCCESS, SPEAKER_LOAD_FAIL } from "../actions/speakers";
  
  const initialState = {
      data: [],
      isLoading: false,
      hasErrored: false,
      errorMessage: ''
  }
  
  export function speakers(state = initialState, action) {
      switch (action.type) {
          case SPEAKER_LOAD:
              return Object.assign( {}, state, {
                      isLoading: true,
                      hasErrored: false
                  }
              );
              break;
                  
          case SPEAKER_LOAD_SUCCESS:
              return Object.assign( {}, state, {
                  isLoading: false,
                  hasErrored: false,
                  data: action.payload.data
              });
              break;
          
          case SPEAKER_LOAD_FAIL:
              return Object.assign( {}, state, {
                  isLoading: false,
                  hasErrored: true,
                  errorMessage: action.error.message
              })
              break;
  
          default:
              return state;
              break;
      }
  }
  ```

6. Combine the reducers in a single file ```/redux/reducers/index.js```. This is the reducer that will be imported from the store in 3:

  ```JavaScript
  import { combineReducers } from "redux";
  import { speakers } from "./speakers";
  
  export default combineReducers({
      speakers
  });
  ```
  
7. Link the app with the store. To do this, wrap the app/router with the ```Provider``` component. In this case, the initial state comes from the ```window.__STATE__``` global variable 

  ```JavaScript
  import React from 'react';
  import ReactDOM from 'react-dom';
  import { browserHistory } from 'react-router';
  import { BrowserRouter as Router } from 'react-router-dom';
  import FullPage from './components/common/FullPage';
  
  import { Provider } from "react-redux";
  import configureStore from "../redux/configureStore";
  const store = configureStore(window.__STATE__);
  
  ReactDOM.render(
      <Provider store={store}>
          <Router history={browserHistory}>
              <FullPage />
          </Router>
      </Provider>,
      document.getElementById("app")
  );
  
  ```

8. Use the store from the needed components. Most of the time, the store's clients are the TopLevelComponents (The ones that handle the state. i.e. PageComponent):

  ```JavaScript
  import React, {Component } from "react";
  import Header from "./Header";
  import List from "./List";
  import { connect } from "react-redux";
  import { speakersFetchData } from "../../../redux/actions/speakers";
  
  class SpeakersPage extends Component {
      
      constructor(props) {
          super(props);
          this.state = {
              appData: [],
              isLoading: true
          }
      }
      
      componentDidMount() {
          this.props.speakersFetchData();
      }
  
      render() {
          return(
              <div>
                  <Header />
                  <List speakers={this.props.speakers} isLoading={this.props.isLoading}/>
              </div>
          );
      }
  }
  
  const mapStateToProps = (state) => {
      console.log(state);
      return {
          speakers: state.speakers.data,
          isLoading: state.speakers.isLoading,
          hasErrored: state.speakers.hasErrored,
          errorMessage: state.speakers.errorMessage
      };
  };
  
  export default connect(mapStateToProps, {speakersFetchData})(SpeakersPage); //1) mapStateToProps 2) mapDispatchersToProps
  ```
  
  The important things to note here are:
  - ```componentDidMount``` triggers the action from the dispatcher method.
  - The ```mapToStateProps``` function will receive the state that outcomes from the reducer. In that state, the ```speakers``` property comes from the merged reducer. This function will be used to map the desired members from the state with members from the ```props``` object.
  - The ```render()``` method don't use the state any more. Instead, uses the props mapped from the ```mapToStateProps```

以上是关于markdown 介绍一个React y Redux的主要内容,如果未能解决你的问题,请参考以下文章

Redux,基础

高级前端面试题大汇总(只有试题,没有答案)

「ReStory」在 Markdown 中自由书写 React 组件 (Beta)

mk-js,一个基于reactnodejs的全栈框架

React Private Route 高阶组件?

在React中使用Redux