Einfaches Beispiel mit React und Redux auf der Client-Seite

View more Tutorials:

1- Das Ziel des Beispiel

In dieser Unterricht werde ich Sie bei der Erstellung einer kleinen Applikation mit  React & Redux anleiten. Darin hilft die Bibliothek  Redux bei der Management des Status der Applikation. Alle Die ganze Applikation läuft bei der Seite vom   Client (Client Side).
Unter ist das die Demo-Image von der Applikation
Die Bibliothek werden in dieser Applikation verwendet
Libraries
<!--
   NOTE: Check other version at: https://cdnjs.com
   -->
<!-- React Libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>

<!-- Redux & React-Redux Libraries -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.7/react-redux.min.js"></script>

<!-- Babel Library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>

Die Architektur vom Redux:

Sie können meinen Artikel  "Die Vorstellung über Redux" nach der folgenden Link lesen um  Redux und seine Architektur besser zu kennen und sowie den Unterschied zwischen  Flux und  Redux zu lernenn.

2- Die Kode der Applikation

Erstellen Sie 2 Files  react-redux-example.html & react-redux-example.jsx:
react-redux-example.html
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8">
      <title>React/Redux for beginners</title>
      <!--
         NOTE: Check other version at: https://cdnjs.com
      -->
      <!-- React Libraries -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>

      <!-- Redux & React-Redux Libraries -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.0/redux.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.7/react-redux.min.js"></script>

      <!-- Babel Library -->
      <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>

      <style>
        table {
          border-collapse: collapse;
        }
        table td, th {
          padding: 5px;
        }
      </style>
   </head>
   <body>

     <p>Install
       <a target="_blank"
         href="https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd/related?hl=en">
         Redux DevTools
       </a>
       Chrome Extension to see under the hood
     </p>

      <div id="app">
         Loading...
      </div>

      <script type="text/babel" src="react-redux-example.jsx"></script>

   </body>
</html>
 
react-redux-example.jsx
// REACT COMPONENT
// Generally you would spilt this up into logical components
// and pass props around correctly etc but we are keeping it as simply as possible
class ProductsPane extends React.Component {
  constructor (props, context) {
    super(props, context);
  }

  // EVENT HANDLERS
  // They are responsible for calling `dispatch` which will send events to redux
  addProduct = () => {
    var action = {
        type: 'ADD_PRODUCT'
    };
    this.props.dispatch(action);
  }

  removeProduct  = (productId) =>  {
    var action = {
      type: 'REMOVE_PRODUCT',
      productId: productId
    };
    this.props.dispatch(action);
  }

  editProduct = (productId, event) =>   {
    var newName =  event.target.value;
    var action = {
      type: 'EDIT_PRODUCT',
      data: {
        productId: productId,
        productName: newName
      }
    };
    this.props.dispatch(action);
  }


  render () {
    const products = this.props.products;

    // Example product: { productId : 4 , productName :'Profit' }
    var trList = products.map( (product, index) => {
      return (<tr key={product.productId}>
        <td>{product.productId}</td>
        <td><input type="text" onChange={this.editProduct.bind(null, product.productId)} value={product.productName} /></td>
        <td>
          <button onClick={this.removeProduct.bind(null, product.productId)}>
             Remove
          </button>
        </td>
      </tr>);
    });


    return (<div>
      <table border="1">
        <thead>
           <th>ID</th>
           <th>Product Name</th>
           <th>Remove</th>
        </thead>
        <tbody>
          {trList}
        </tbody>
      </table>
      <br/>
      <button onClick={this.addProduct}>
          Create
      </button>
    </div>);
  }
}

var nextProductId = 10;

// MAP STATE TO PROPS
// Probably the most important method of the demo which handles the React/Redux integration.
// When state changes, this method is called, which then you can use to customly
// map the state into props that your React component can use
// MAP: state.productList <==> props.products
const mapStateToProps = (state) => {
  return {
    products: state.productList
  }
}

// Example product: { productId : 4 , productName :'Profit' }
const getIndexByProductId = (products, productId)  => {
    for(var i = 0; i < products.length; i++) {
       var product = products[i];
       if(product.productId === productId) {
         return i;
       }
    }
    return -1;
};



// REDUCERS
// Reducers listen for actions that are dispatched and react depending on your logic
// All state in Redux is immutable(never changes) so we always have to return a new
// state object.
// We are going to copy the current state and return a new one based off the action creators above
const appReducer = (state = {productList: []}, action) => {

  // Clone Array.
  let products = state.productList.slice();
  // This is quite a common way of deciding which event to process
  // Note: ALL events will be coming through this reducer
  console.log('Actions', action); // Open your console to see what actions look like

  // Even better, install Redux DevTools and your mind will be blown
  switch (action.type) {
    case 'ADD_PRODUCT':
      nextProductId++;
      var product = {productId : nextProductId, productName: "" };
      products.push(product);
      break;
    case 'REMOVE_PRODUCT':
      var idx = getIndexByProductId(products, action.productId);
      if(idx != -1)  {
        products.splice(idx, 1); // Removes element at `idx`
      }
      break;
    case 'EDIT_PRODUCT':
      var idx = getIndexByProductId(products, action.data.productId);
      if(idx != -1)  {
          products[idx].productName = action.data.productName;
      }
      break;
  }
  // As above, we have to return a new state object each time (Redux store is immutable)
  // It makes sure we know our data can only be modified in one visible way
  // Also lets us time travel through our application state!
  const newState = {
    productList: products
  }
  console.log('Current State', newState);
  return newState;
}

// REDUX STORE
// Create store initializes our Redux store and only has to be called once
// The first argument is our `appReducer` defined above, it is almost like a listener
// The second is just our initial state which is just a Javascript object
// The third is usually where enhancers/middleware goes
// In this example it just loads Redux DevTools so everyone can play around
let store = Redux.createStore(appReducer, {
  productList: [
    { productId : 1 , productName :'React' },
    { productId : 2 , productName :'Redux' },
    { productId : 3 , productName :'Profit' }
  ]
}, window.devToolsExtension ? window.devToolsExtension() : undefined);

// We want to use Redux connect to attach our mapStateToProps to our ProductsPane (React Component)
const MyApp = ReactRedux.connect (
  mapStateToProps
)(ProductsPane);

// Render
ReactDOM.render(
  <ReactRedux.Provider store={store}>
    <MyApp />
  </ReactRedux.Provider>,
  document.getElementById('app')
);


if (window.devToolsExtension) {
  window.devToolsExtension.open();
}
 
Die File  react-redux-example.html auf  HTTP Server laufen:

3- Die Kode der Applikation erklären

OK, In dieser Applikation verwenden wir  React und  Redux. Davon ist  Redux eine Bibliothek  Javascript zum Management des Status der Applikation. Die folgende Image bezeichnet die Architektur vom  Redux.
Wenn der Benutzer auf die Interface der Applikation interaktivieren (z.B den Maus klicken), eine Methode vom Component aufgeruft zu implementieren. In dieser Methode wird ein Objekt action erstellt. Es ist ein reines Objekt, das die betreffenden Informationen von Events und den aktualisierenden Status enthalten. Zum letzten wird das Objekt zu STORE durch die Aufruf von  this.props.dispatch(action) geschickt.
REDUCER: ist eine Funktion  Javascript, und Sie müssen die Kode für diese Funktion schreiben um einen neuen Status für die Applikation zurückzugeben. Er hat 2 Parameters:
  1. Der Parameter 1: der originale Status der Applikation.
  2. Der Parameter 2: Das Objekt action wurde im letzten Schritt geschickt.
Im  Redux ist  STORE einzig. Es speichert den Status der Applikation und enthaltet die  Reducer und  Middleware. Sie können eine  STORE durch die Methode   Redux.createStore(..) erstellen.
// createStore method:
Redux.createStore(reducer, [preloadedState], [enhancer])

// @see API docs: https://redux.js.org/api/createstore
Nachdem  action auf  STORE behandelt wird, wird ein neuer Status für  VIEW PROVIDER zurückgegeben.
Der neu aktualisierte Status für  Component:

API:

View more Tutorials: