1. 程式人生 > >React......在一天之內

React......在一天之內

Visual Studio 2017中設定React專案

我過去曾多次在工作要求中找到“React”並在Angular中進行開發,我總是想知道這兩個單頁應用程式框架有多麼不同。好吧,我想我等不及了,在一次面試中,他們讓我開發一個簡單的React頁面。我感到很驚訝,但我們不應該在面試中說我不能

首先要提到的是專案定義,如下所示:使用React建立一個帶有汽車零件輸入表單的簡單單頁應用程式。

  1. 汽車零件表單必須包含以下欄位
      1. ID(唯一識別符號,可以自動生成)。
      2. 部件號(從
        00001開始的隨機5位數字)。
      3. 零件名稱(汽車零件名稱)。
      4. 描述(描述汽車部件)。
      5. 汽車製造商名稱(克萊斯勒,道奇,福特等)
  2. 應用程式必須能夠將汽車零件條目儲存到資料庫
  3. 應用程式必須能夠編輯汽車零件條目
  4. 應用程式必須能夠刪除汽車零件條目

為了完成專案,我決定使用Visual Studio 2017,並在考慮這些要求的情況下探索React框架。幸運的是,網際網路在任何主題中都提供了無數的資源。所以按步驟我進行如下:

建立一個React專案

這是任何.NET開發人員都知道的一個步驟。但過程如下:

  1. 開啟
    Visual Studio 2017並選擇建立新專案
  2. 在彈出視窗中選擇專案型別,在本例中為ASP.NET Core Web Application。這是.NET Core模板組的一部分。
  3. 選擇專案的資料夾位置,指定專案名稱(React Demo)和解決方案名稱(React Demo)。
  4. 檢查建立解決方案目錄選項。
  5. 如果您有一個GIT帳戶,並且您希望將此專案保留在GIT中,那麼也要檢查該選項。
  6. 單擊確定後,下一個視窗將顯示不同的專案模板。選擇ReactJS模板,然後單擊確定
  7. 第一個視窗應該是這樣的。第二個視窗非常簡單,所以我沒有在這裡顯示它,但它需要選擇
    ReactJS選項並單擊確定。

https://www.codeproject.com/KB/applications/1271257/fig1.png

解決方案資源管理器將是這樣的:

https://www.codeproject.com/KB/applications/1271257/fig2.png

這是我們在執行專案時得到的:

https://www.codeproject.com/KB/applications/1271257/fig3.png

好吧!一個錯誤。如果我們選擇專案名稱並單擊顯示所有檔案,我們將注意到沒有node_modules資料夾。因此,我們的第一步是在專案檔案級別開啟命令提示符並執行NPM Install。第二次我們執行專案...... 搞定了!

https://www.codeproject.com/KB/applications/1271257/fig4.png

對於一個我們可能不需要的額外內容的專案來說,這是一個很好的起點。在我們的例子中,我們不需要CounterFetch Data選單項和相關頁面。我們需要首頁,但我們可能需要更改該文字。為了提交React演示,我決定將主頁中的文字替換為專案要求。結果將是這樣的:

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
 export class Home extends React.Component<RouteComponentProps<{}>, {}> {
   public render() {
       return <div>
           <h1>React Demo</h1>
           <p><u>Tasks:</u></p>
           <p>Make a simple one-page application with a car part entry form.</p>
           <p>Car part entry form must have the following fields:</p>
           <ul>
               <li>ID (unique identifier, can be automatically generated).</li>
               <li>Part Number (random 5-digit number starting with 00001.</li>
               <li>Part name (name of car part. </li>
               <li>Description (describe the car part).</li>
               <li>Car Manufacturer Name (Chrysler, Dodge, Ford, etc.)</li>
           </ul>
           <p>App must be able to save the car part entries to a database</p>
           <p>App must be able to edit car part entries</p>
           <p>App must be able to remove car part entries</p>
       </div>;
   }
}

我還決定刪除CounterFetch Data並新增React Demo。第一步是一個簡單的步驟,只打開Home.tsx檔案並替換文字。第二步需要您開啟NavMenu.tsx檔案。在該檔案中刪除以下行:

<li>
     <NavLink to={ '/counter' } activeClassName='active'>
         <span className='glyphicon glyphicon-education'></span> Counter
     </NavLink>
</li>
<li>
     <NavLink to={ '/fetchdata' } activeClassName='active'>
         <span className='glyphicon glyphicon-th-list'></span> Fetch data
     </NavLink>
 </li>

並用以下程式碼替換它們:

<li>
    <NavLink to={ '/reactdemo' } activeClassName='active'>
         <span className='glyphicon glyphicon-education'></span> React Demo
    </NavLink>
</li>

同樣在routes.tsx檔案中刪除counterfetchdata路由,並將其替換為“carpart”路由,如下所示:

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';;
import { CarPart } from './components/ CarPart;
export const routes = <Layout>
   <Route exact path='/' component={ Home } />
   <Route path='/ carpart component={ CarPart } />
</Layout>;

我們可以刪除Counter.tsxFetchData.tsx並新增一個新的carPart.tsx。要新增carPart tsx檔案,我剛僅新增一個typescript檔案,並將其副檔名更改為tsx。以下程式碼顯示了CarPart元件的詳細資訊。

此元件有兩個事件方法HandleSaveHandleDelete,單擊相應按鈕時會觸發這些方法。我們在這些方法中需要注意的是react Fetch的呼叫。在HandleSave的情況下,它包含頭資料並將物件作為頭的一部分作為JSON物件傳遞,這樣,在控制器中,SavePartData方法中CarPartModel型別的引數carPart將使用[FromModel]進行修飾,這意味著沒有必須對映任何東西來傳遞和物件例項。

HandleDelete的情況下,唯一需要的引數是將從資料庫中刪除的部件ID

import 'bootstrap/dist/css/bootstrap.min.css';
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import Link, { LinkedComponent } from 'valuelink';
interface CarPartModel {
  ID: number;
  PartNumber: number;
  PartName: string;
  Description: string;
  CarManufacturer: string;
}
const carManufacturers = [
  { label: "Ford", value: 1 },
  { label: "Chevrolett", value: 2 },
  { label: "Tesla", value: 3 },
  { label: "Chrysler", value: 4 },
  { label: "Honda", value: 5 },
  { label: "Toyota", value: 6 },
];
export class CarPart extends React.Component<RouteComponentProps<{}>, CarPartModel> {
  state: CarPartModel = {
      ID: 0,
      PartNumber: 0,
      PartName: '',
      Description: '',
      CarManufacturer: ''
  };
  constructor() {
      super();
      this.state = {
          ID: 0,
          PartNumber: 0,
          PartName: '',
          Description: '',
          CarManufacturer: ''
      };
      this.handleSave = this.handleSave.bind(this);
      this.handleDelete = this.handleDelete.bind(this);
  }
  handleSave = () => {
      fetch('api/CarParts/SavePartData', {
          method: 'post',
          headers: new Headers({
              "Content-Type": "application/json",
              Accept: "application/json"
          }),
          body: JSON.stringify(this.state)
      }).then(function (response) {
          if (response.status !== 200) {
              console.log('fetch returned not ok' + response.status);
          }
      }).catch(function (err) {
          console.log(`error: ${err}`);
          })
  }
  handleDelete = () => {
      if (!confirm("Do you want to delete employee with Id: " + this.state.ID))
          return;
      else {
          fetch('api/CarParts/Delete/' + this.state.ID, {
              method: 'delete'
          }).then(data => {
              this.state =
                  {
                      ID: 0,
                      PartNumber: 0,
                      PartName: '',
                      Description: '',
                      CarManufacturer: ''
                  };
          });
      } 
  }
  public handleIdChange(event: any): void {
      this.state.ID = event.target.value;
  }
  public handlePartNumberChange(event: any): void {
      this.state.PartNumber = event.target.value;
  }
  public handlePartNameChange(event: any): void {
      this.state.PartName = event.target.value;
  }
  public handleDescriptionChange(event: any): void {
      this.state.Description = event.target.value;
  }
  public handleManufacturerChange(event: any): void {
      this.state.CarManufacturer = event.target.value;
  }
  public render() {
      return <div>
          <h1>Car Parts</h1>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Id: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="partId" onChange={e => this.handleIdChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Number: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text " name="partNumber" onChange={e => this.handlePartNumberChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Part Name: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="partName" onChange={e => this.handlePartNameChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>               
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Description: </label>
              </div>
              <div className='col-md-2'>
                  <input className="form-control" type="text" name="description" onChange={e => this.handleDescriptionChange(e)} required />
              </div>
              <div className='col-md-8'>
              </div>
          </div>
          <div className='row'>
              <div className='col-md-2'>
                  <label>Car Manufacturer:</label>
              </div>
              <div className='col-md-2'>
                  <select onChange={e => this.handleManufacturerChange(e)}>
                      <option value="volvo">Volvo</option>
                      <option value="saab">Saab</option>
                      <option value="mercedes">Mercedes</option>
                      <option value="chrysler">Chrysler</option><option value="saab">Saab</option>
                      <option value="dodge">Dodge</option>
                      <option value="ford">Ford</option>
                  </select>
              </div>
              <div className='col-md-8'>
              </div>               
          </div>
          <div className='row mt-3'> </div>
          <div className='row'>
              <div className='col-md-1'>
                  <button onClick={this.handleSave} className='btn btn-info btn-lg'><span className="glyphicon glyphicon-ok"></span>
                      &nbsp;&nbsp;Save
                  </button>
              </div>
              <div className='col-md-1'>
                  <button onClick={this.handleDelete} className='btn btn-info btn-lg'><span className="glyphicon glyphicon-remove"></span>
                      &nbsp;&nbsp;Delete
                  </button>
              </div>
              <div className='col-md-9'>
              </div>
          </div>
          </div>
          ;
  }
}

我新增的最後一項是專案服務。為此,我添加了一個services資料夾,並添加了一個名為CarPartService.cs的類和ICarPartService.cs介面。服務類具有c#中的實際程式碼,該程式碼將與資料訪問層(DAL)互動以執行CRUD操作。我沒有在演示中包含它,因為它超出了專案目的範圍,專案目的是顯示使用React程式碼的能力。但是出於測試目的,在服務方法中新增斷點並在除錯中執行應用程式。

ICarPartInterface.cs的內容如下:

using ReactSample.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ReactSample.Services
{
   public interface ICarPartService
   {
       CarPartViewModel GetCartPart(int carPartId);
       bool SaveCartPart(CarPartViewModel carPart);
       bool UpdateCarPart(CarPartViewModel carPart);
       bool Delete(int carPartId);
   }
}

CarPartService.cs的程式碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ReactSample.ViewModels;
namespace ReactSample.Services
{
   public class CarPartsService : ICarPartService
   {
       public bool Delete(int carPartId)
       {
           try
           {
               // Find the car part associated with the given Id and delete it
               return true;
           }
           catch(Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
       public CarPartViewModel GetCartPart(int carPartId)
       {
           var carPart = new CarPartViewModel();
           try
           {
               // Find the car part associated with the given Id, polulate carPart object and return it
               return carPart;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return null;
       }
       /// <summary>
       /// Receives car part object and query database
       /// if record exists then updates
       /// if record does not exist then inserts
       /// </summary>
       /// <param name="carPart"></param>
       /// <returns></returns>
       public bool SaveCartPart(CarPartViewModel carPart)
       {
           try
           {
               // Save the car part object into database
               return true;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
       public bool UpdateCarPart(CarPartViewModel carPart)
       {
           try
           {
               // Find the car part associated with the given Id and update fields using parameter object
               return true;
           }
           catch (Exception ex)
           {
               // Log error message in case of error
           }
           return false;
       }
   }
}

為了使用服務層,我決定將它注入控制器。所以我在Controllers資料夾中建立了一個CarPartsController並添加了以下程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ReactSample.Services;
using ReactSample.ViewModels;
namespace ReactSample.Controllers
{
   [Produces("application/json")]
   [Route("api/[controller]")]
   public class CarPartsController : Controller
   {
       ICarPartService _carPartService;
       private readonly string[] CarManufacaturers = new[]
       {
           "Chryssler", "Dodge", "Ford", "Jeep", "Chevrolett", "Honda", "Toyota", "Subaru", "Nisan", "Kia"
       };
       public CarPartsController(
           ICarPartService carPartService
       )
       {
           _carPartService = carPartService;
       }
       [HttpGet("{id}", Name = "Get")]
       public CarPartViewModel Get(int id)
       {
           return _carPartService.GetCartPart(id);
       }
       [HttpPost("SavePartData")]
       public void SavePartData([FromBody]CarPartViewModel carPart)
       {
           _carPartService.SaveCartPart(carPart);
       }
       // PUT: api/Sample/5
       [HttpPut("{id}")]
       public void Update(int id, [FromBody]CarPartViewModel carPart)
       {
           _carPartService.UpdateCarPart(carPart);
       }
       // DELETE: api/ApiWithActions/5
       [HttpDelete("Delete/{id}")]
       public void Delete(int id)
       {
           _carPartService.Delete(id);
       }
   }
}

你可以注意到在演示中我在這個控制器中使用了兩個方法,SavePartDataDelete。我把了其他方法保留,以防我決定為這個專案新增更多功能......只是為了好玩。如果您注意到此控制器建構函式具有分配給_carPartService變數的carPartService引數。為了完成這項工作,我們需要將以下行新增到Starup.cs檔案中,ConfigureServices方法最後將看起來像這樣的:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ICarPartService, CarPartsService>();
    services.AddMvc();
}

新增bootstrap並執行解決方案後,我們得到:

https://www.codeproject.com/KB/applications/1271257/fig5.png

https://www.codeproject.com/KB/applications/1271257/fig6.png

快樂的編碼!

 

原文地址:https://www.codeproject.com/Articles/1271257/React-in-one-day