iT邦幫忙

0

[筆記]動態<input type="file" /> 新增&刪除&圖片預覽-React.js

開頭

  • 基礎 使用javascript 透過按鈕新增刪除欄位
  • 進階 新增圖片並有圖片預覽功能

基礎

Demo:
https://codepen.io/Candas/pen/pdRwLb
先做出基礎:新增刪除欄位,觀念是設定一個陣列,新增就是array.push 一個元素,刪除就是 array.splice 移除一個元素,顯示出這些欄位而是用map()去跑陣列。

新增:因為push需要有東西給他塞進去,所以我們就新增input的name屬性,
然後再this.setState() 更新 input

  appendInput(e) {
    e.preventDefault();
    this.state.inputs.push({ name: null });
    this.setState({ inputs: this.state.inputs });
  }

刪除:index為當前陣列最尾端,使用array.splice 從index位置開始移除一個元素,並用this.setState 更新 input

splice()

removeInput(index) {
    this.state.inputs.splice(index, 1);
    this.setState({
      inputs: this.state.inputs,
    });
  }

<input>列表

在 render()下面定變數 inputList ,將input.map出來就會出現<input>的列表

    let inputList = this.state.inputs.map((input, index) => {
      let ref = "input_" + index;
      return (
        <div key={index}>
          <input type="file" key={input} ref={ref} />
          <button id={ref} onClick={this.removeInput.bind(this, index)}>
            刪除
          </button>
        </div>
      );
    });

進階

Demo:

https://codepen.io/Candas/pen/jayGWv?editors=0010

這次新增了圖片預覽,直接看code

圖片預覽

會用會用到 FileReader()跟用·e.target 抓欄位資訊 不懂可用consol.log看他們在幹嘛

reader.onloadend()是FileReader的函式,handleImageChange() 主要概念呢一樣 用一個 Array 儲存reader.result 也就是本地的圖片網址 圖片預覽圖片預覽其實就是用本地網址去讀取,目前建議改用WINDOW.URL.CREATEOBJECTURL
因為FileReader會把圖片轉成base-64 檔案比較大 圖片太大會loading 不優,

這邊有個小技巧
這是當你回心轉意 設完欄位上傳完圖片還想再改圖片就需要用它防止bug,不信等等下課把他刪掉你就知道了
,因為圖片預覽一樣是用push()去加 如果想要在新增欄位會繼續push 所以要確認說 你目前是array長度有沒有超過當前的長度,沒有就改該位置的圖片網址就好

 if (this.state.imagePreviewList.length < index) {
        this.state.imagePreviewList.push(reader.result);
      } else {
        this.state.imagePreviewList[index] = reader.result;
      }
 // 圖片大預覽建議使用 WINDOW.URL.CREATEOBJECTURL
  handleImageChange(e, index) {
    e.preventDefault();
    let reader = new FileReader();
    let file = e.target.files[0];
    console.log(reader);
    reader.onloadend = () => {
      // 假設目前不是修改預覽圖片 那就新增預覽圖片
      if (this.state.imagePreviewList.length < index) {
        this.state.imagePreviewList.push(reader.result);
      } else {
        this.state.imagePreviewList[index] = reader.result;
      }
      this.setState({
        file: file,
        imagePreviewList: this.state.imagePreviewList
      });
    };
    console.log(this.state.imagePreviewList);
    reader.readAsDataURL(file);
  }

結語

2018 鐵人賽要到了,不過我目想參加,為了不斷文章很累啊,平常當鐵人就好,不要比賽在當

尚未有邦友留言

立即登入留言