react項目經驗


調用后返回上一頁&&跳轉至當前頁

 this.props.history.goBack();   返回
 this.props.history.push("/index/setting/basicsetting"); 跳轉
 this.props.history.go(-1)  跳轉

當使用時出現以下錯誤Cannot read property 'push' of undefined,
因為父組件調用子組件定義的跳轉事件時,要傳遞history,這里history未定義
(比如app.js這個組件,一般是首頁,不是通過路由跳轉過來的,而是直接從瀏覽器中輸入地址打開的,如果不使用withRouter此組件的this.props為空,沒法執行props中的history、location、match等方法)
解決方法:
import React from "react";
import {withRouter} from "react-router-dom";   //第一,引入withRouter

class MyComponent extends React.Component {   
  ...
  myFunction() {
    this.props.history.push("/some/Path");
  }
  ...
}
export default withRouter(MyComponent);   //第二,不要在上面暴露模塊,在這里使用withRouter暴露模塊

詳細可見:react-router v4 使用 history 控制路由跳轉   https://github.com/brickspert/blog/issues/3

調用后重新渲染當前頁&&跳轉至當前頁

 this.props.history.go(0)  跳轉



 state={
   visible:false
 }
 handleClick=()=>{
    this.setState({
       visible:true
     });
   }
 this.setState(this.state)  //此語句執行過后頁面重新渲染state。這里需要注意的事重新渲染會將visible渲染成state里的false,而不是handleClick里的true
//渲染會把state里的內容全部重新渲染,即執行this.setState(state)之后,visible會被重新渲染為false,若需要visible為true,可以在渲染之后重新定義狀態,如下重新定義
 this.setState({this.state})
 this.setState({
      visible:true
   });



 定義componentWillMount=async()=>{   
        this.getData(); //重新渲染當前頁面
    }  // 使用:調用this.getData();函數即可
    async getData(){
        代碼段
    }

代碼解析

let {state}=this;  // 即 let state = this.state;

let res = await api.SettingGetInfo(this.props.match.params)   //獲取列表里當前元素的id值,此方法需要注意有一個必要條件在route頁面里的route添加  /:id
//即<Route path="/index/setting/basicsetting/:id" component={BasicSettting} />


rowKey={record=>record.id}    //表格table中的每個記錄應該有唯一的“key”支持,或者將“rowKey”設置為唯一的主鍵,否則會報錯。這里是給表格設置rowKey

點擊按鈕復制相關內容(這里以復制鏈接為例)

  npm i --save copy-to-clipboard   //首先安裝相關包

  import copy from 'copy-to-clipboard';  //引入模塊

  render:(a, code, index)=>{
                return <span>
                    <a href="# "  onClick={()=>{this.copyLink(code)}}>復制鏈接</a>
                </span>
            }

  copyLink=(code)=>{
        copy(`https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${code.info}`)
        message.success("鏈接復制成功",2.5)
    }

三目運算符的嵌套使用

正常使用:code.type===1?(adate<bdate?atime:btime):<span className="text-success">永不</span>

react里:{title:"時間",dataIndex:"Time",render(a,code,index){
                let adate=...;
                let bdate=...;
                var overtime=<span className="text-danger">時間不足</span>;
                var forevertime=<span className="text-success">永久</span>
                var times=`${date.getFullYear()}-${date.getMonth() + 1<10?"0"+(date.getMonth()+1):date.getMonth()+1}-${date.getDate()<10?"0"+date.getDate():date.getDate()} ${date.getHours()<10?"0"+date.getHours():date.getHours()}:${date.getMinutes()<10?"0"+date.getMinutes():date.getMinutes()}:${date.getSeconds()<10?"0"+date.getSeconds():date.getSeconds()}`   //將時間戳轉換為日期格式

                return <span>{code.type===1?(adate<bdate?overtime:times):forevertime}</span>  //嵌套使用
            }}

======================================================================================================================================================

接口部分

讀懂接口文檔


/api/wechat/code/:officialId/:qrcodeId  帶冒號,動態數據:`${base}/api/wechat/code/${localStorage.getItem("listid")}/${params.id}`  //這列的:qrcodeId需要使用${params.id}動態寫入,params即數組
/api/wechat/statistics/:officialId/code  不帶冒號,靜態的:`${base}/api/wechat/statistics/${localStorage.getItem("listid")}/code`  //這里的qrcode直接寫上去就可以
 

參數問題

  request<T = any>(config: AxiosRequestConfig): AxiosPromise<T>;   //request 一個參數  config
  get<T = any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>;  //get  兩個參數 url config
  delete(url: string, config?: AxiosRequestConfig): AxiosPromise;  //delete  兩個參數  url config
  head(url: string, config?: AxiosRequestConfig): AxiosPromise;   //head  兩個參數 url config
  post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>;  //post 三個參數 url data config
  put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>; // put 三個參數 url data config
  patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise<T>; // patch 三個參數 url data config

參數解釋 :url —— 請求地址
                   data——發送給服務器的請求數據
                   config——配置,一般都是固定格式

舉個栗子:
  export default{
        async codeDesign(params){                                                 
                return await axios.put(`${base}/api/code/${localStorage.getItem("listid")}/${params.id}`, params,{  //url data
                          headers:{                         //config  一般都是固定格式
                               "token":cookie.load("usertoken")
                          }
                }).then((res)=>{
                      return res.data;
                });
       },
        async codeExtend(params){
        return axios.post(`${base}/api/code/${localStorage.getItem('listid')}/${params.id}/extend`,{},{   //這里data就沒有傳參,而是用{}表示
            headers:{
                "token":cookie.load("usertoken")
            }
        }).then((res)=>{
            return res.data;
        });
    },
      async codeGetMsg(params){
              return await axios.get(`${base}/api/code/${localStorage.getItem("listid")}/${params.id}`,{
                  params,       **//如果是get delete兩個參數的這種,是沒有data參數的,那么params不能放在data里,就可以放在config里**
                  headers:{
                      "token":cookie.load("usertoken")
                  }
              }).then((res)=>{
                  return res.data;
              });
          },
  }

注意:需要的參數,一個都不能少,data如果不需要傳,設置為{}都行,也不能不傳

axios實戰舉例

state={

    //上傳接口的參數
    title:"",   
    author:"",
    digest:"",
    content:"",

    piclist:[],   //從服務器獲取的圖片數組
    picTotal:2,   
    filter:{         
        isloading:false,
        type:"image",
        flag:2,
        page:1,
        pageSize:18,
      },
}

//上傳pictextData數據到服務器
    addPictext=async()=>{
        let {title,author,digest,content}=this.state.pictextData;
        if(!title){
            this.setState({
                pictextTitleRemind:true
            })
            return;
        }else{
            this.setState({
                pictextTitleRemind:false
            })
        }
        if(!(/^(((https?):\/\/|\w+(\.\w+)+)(:\w+)?).*/.test(contentSourceUrl))){   //匹配正則
            this.setState({
                urlRemind:true
            })
            return;
        }else{
            this.setState({
                urlRemind:false
            })
        }
        let data=await api.pictextAdd({
            title,
            author,
            digest,
            content,
        })
        if(data.code!==0){
            console.log(api.stateCode[data.code]);
            return;
        }
        if(data.code===0){
            message.success("保存成功!",3);
            this.props.history.push("/index/setting/pictextIndex");
        }
    }

componentWillMount=async()=>{   //render加載之前就獲取到圖片信息
      this.getData();
    }

//獲取圖片的接口
async getData(){
      this.setState({
        filter: Object.assign(this.state.filter, {
            isloading: true
        }),
        
      });
      let res=await api.picGetList(this.state.filter)
     this.setState({
        filter: Object.assign(this.state.filter, {
            isloading: false
        }),
      if(res.code===0){
        this.state.picTotal=res.data.total;
        this.state.piclist=res.data.data;
      }else{
        console.log(api.stateCode[res.code]);
      }
      this.setState(this.state);  //重新渲染頁面
    }

//分頁
    onChangePage = (page = 1, pageSize = 18) => {
      this.setState(
          Object.assign(this.state.filter, {
              page,pageSize
          })
      );
      this.getData();  //重新加載getData函數,為了重新渲染頁面
    }

//刪除圖片接口
    deletePic=async(item)=>{
      this.setState({
        imgDelete:false,
        picImgDelete:false,
      })
      let data=await api.picDelete({
        id:item.id,    //獲取需要刪除的圖片的id
      })
      if(data.code!==0){
        console.log(api.stateCode[data.code]);
        return;
      }else if(data.code===0){
        this.onChangePage();
        message.success(`刪除成功!`,2.5);
      }
      this.getData();
    }

<Pagination hideOnSinglePage onChange={this.onChangePage} current={this.state.filter.page} pageSize={this.state.filter.pageSize} total={this.state.picTotal}  />  //antd分頁頁標

受控組件和不受控組件

在HTML中,<textarea> 的值是通過子屬性設置的。在React中,需要通過value設置。我們可以通過添加事件屬性onChange監聽內容的變化,onChange會在下列情況下被觸發:
input或者textarea的內容改變
input的checked狀態改變
select的狀態改變

【受控組件】
設定了value的input就是一個受控組件。input里會一直展現這個值,用戶的任何輸入都是無效的。如果你想隨着用戶的輸入改變,使用onChange事件,或者將value改為defaultValue

【非受控組件】
value沒有值或者值設為null的input是一個不受控組件。用戶的任何輸入都會反映到輸入框中
這個時候也可以監聽onChange事件,內容的改變也會觸發事件。
可以通過defaultValue給input設置默認值

指定編輯(如刪除,更新等)

有一種需求是點擊table中當前tr的“編輯”按鈕后,跳轉到新的編輯頁面編輯當前tr的信息。
這種情況是需要動態獲取id的
方法如下:
1、在route.js即路由頁面將編輯頁面的路由給一個/:id,如下
<Route path="/index/setting/code/code-edit/:id" component={codeEdit} />   //注意是/:id  /別忘了
2、列表頁面編輯按鈕的Link跳轉給一個動態id(該id由后端接口數據里給出),如下
<Link to={`/index/setting/code/code-edit/${codelist.id}?id=${codelist.id}`} className="mr-10px">編輯</Link>
3、在編輯頁面對接接口時,參數應使用this.props.match.params
async getPictextData(){
        let res =await api.pictextGetEdit(this.props.match.params)   //這里傳入的是this.props.match.params
        if(res.code===0){
            state.pictextEditData=res.data;
        }else{
            console.log(api.stateCode[res.code]);
        }
        this.setState(state)
      }

提個醒:this.props.match.params是從另一個頁面通過路由帶到當前頁面的數據。你可以在任何地方使用它。
這也表明了,這個傳遞的數據,不一定得是id,也可以是其他的數據。比如name,size等,通過/:name就可以傳遞
就比如說console.log(this.props.match.params)打印出來的是{"id":"1"}。你就可以通過this.props.match.params.id來獲取到1。
但有一點,這個1可能是字符串類型的。和number類型的不是一個數據類型。所以在做判斷是否相等的時候要注意,用==而不用===
在控制台打印出的數字,黑色的就是string類型。藍色的是number類型

使用搜索框搜索數據(后端接口沒有設置好,全部由前端操作)

state={
    filter: {
                name:"",
                total: 0,
                page:1,
                pageSize:20,
            }
}

handleProductSearch=(e)=>{
        this.setState(
            Object.assign(this.state.filter,{
                name:e.target.value,   //在對接接口之后。若想根據名稱name搜索,將搜索框的event賦值給filter里的name便可
            })
        );
        this.setState(state);  //重新渲染頁面
    }


<Search
    placeholder="請輸入產品名稱"
    onSearch={this.handleProductSearch}
/>

使用搜索框搜索數據,(后端接口已經設置好的情況下)

state={
    filter: {
                name:"",
                total: 0,
                page:1,
                pageSize:20,
            }
}

productName=(e)=>{
     this.setState(
            Object.assign(this.state.filter,{
                name:e.target.value,   //在對接接口之后。若想根據名稱name搜索,將搜索框的值賦值給filter里的name便可
            })
        );
}

handleProductSearch=(e)=>{
        this.productInfoGet();  //調用獲取產品信息的接口。此時的name已經是搜索的name。給接口接口會返回搜索后的結果
    }


<Search
    placeholder="請輸入產品名稱"
    onChange={this.productName}
    onSearch={this.handleProductSearch}
/>

======================================================================================================================================================

localStorage解釋

    localStorage.setItem("key","value");//以“key”為名稱存儲一個值“value”

    localStorage.getItem("key");//獲取名稱為“key”的值

    localStorage.removeItem("key");//刪除名稱為“key”的信息。

    localStorage.clear();​//清空localStorage中所有信息

state里的filter里得數據怎么setState?(使用Object.assign相關知識)

this.state={
            visible:false,
            filter: {
                isloading: false,
                name:"",
                page:1,
                pageSize:20,
            }
        }

這里的isloading怎么設置為true呢?

handleClick=()=>{
        this.setState({
            filter:Object.assign(this.state.filter,{
                isloading:true
            }),
        });
    }

動態添加css樣式(如通過點擊添加css樣式)

state={
    select: "",
}

handleSelect=(item)=>{
    this.setState({
        select: item.id
    })
}

<div onClick={()=>{this.handleSelect(item)}}  style={{border:this.state.select===item.id?"1px solid #28a745":null}}></div> 

動態添加一組可編輯框(如點擊添加按鈕后會添加一個可輸入數值的圖文框)

思路:
1、state一個數組如Data,將數組的值與圖文框綁定起來,通過map函數渲染到頁面
2、當點擊添加按鈕后,執行函數,往list數組里push一組數據,數據會自動渲染到頁面,即實現了動態添加圖文框的功能
3、通過編輯數組的值即可動態編輯圖文框里的內容
4、動態刪除可以通過用數組的splice操作數組的下標index來實現刪除。
總結:通過操作數組的數據來實現圖文框的增刪改,而不是通過dom操作

舉個例子:
state={
    title:"",     //上傳接口的參數
    author:"",
    digest:"",
    content:"",
    Data:[{id:"1",title:"",author:"",digest:"",content:""}],
    boxid:"1", //定義圖文框的id
    msg:[],
    changeBorder:"",
}

//添加圖文框數組
    addBox=()=>{
        this.setState({
            boxid:this.state.boxid++, 
        })
        this.state.Data.push({id:`${this.state.boxid}`,title:"",author:"",digest:"",content:""})
        this.setState(this.state)
    }
//刪除圖文框
listbox_Delete=(item)=>{  
        let index= this.state.Data.indexOf(item)    //獲取需要刪除的圖文框的index
        this.state.Data.splice(index,1)    //使用splice方法刪除數組數據
    }

//向上移動圖文框(通過改變替換index來實現)
listbox_up=(item)=>{
        let index=this.state.Data.indexOf(item)
        let arr=this.state.Data
        let index2=index-1
        if(index2!==0){
            arr[index]=arr.splice(index2,1,arr[index])[0] 
        } 
    }

//向下移動圖文框
listbox_down=(item)=>{
        let index=this.state.Data.indexOf(item)
        let arr=this.state.Data
        let index2=index+1
        if(index2!==arr.length){
            arr[index]=arr.splice(index2,1,arr[index])[0]
        }
    }

//圖文框數組map方式渲染到頁面
{
         this.state.Data.map((item,index)=>{
         if(item.id==1){   //item.id==1時是主圖文框的樣式,否則是副圖文框的樣式
         return <div onClick={()=>{this.handleSelect(item)}} key={index}>   //map語法必須要帶有key={index},不然會報錯
                         <div  >
                             <img src={item.picUrl} alt="" style={{width:"100%",height:"100%"}}/>
                         </div>
                         {item.title?<div className="indexbox_mask">{item.title}</div>:null}
                     </div>
                  }else{
               return <div  key={index} style={{border:this.state.changeBorder===item.id?"2px solid #28a745":null}} onClick={()=>{this.handleSelect(item)}}>    //handleSelect,點擊后選取當前框並與輸入框綁定
                              <h4 style={{height:21}}>{item.title}</h4>
                              <div className="listbox_content">
                                    <div className="listbox_img">
                                            <img src={item.picUrl} alt=""/>
                                    </div>
                              </div>
                              <div className="listbox_mask">
                                      <Icon type="up"className="listbox_icon mr-10px" onClick={()=>{this.listbox_up(item)}} />  //圖文框位置上移
                                      <Icon type="down" className="listbox_icon" onClick={()=>{this.listbox_down(item)}} />  //圖文框位置下移
                                      <div className="float-r">
                                           <Icon type="delete"className="listbox_icon" onClick={()=>{this.listbox_Delete(item)}}/>   //刪除圖文框
                                      </div>
                               </div>
                          </div>
                       }
                 })
             }
    <Button onClick={this.addBox}></Button>  //添加圖文框

//點擊圖文框后選定當前圖文框,並與Input輸入框綁定,之后在Input里輸入的值都會存在當前數組里。再點擊其他圖文框后執行同樣的操作,最后所有圖文框里采集的數據會全部存在Data數組里,通過接口將數組傳入后台,再在另一個頁面獲取並渲染該組數據,即完成了前后端的一個交接流程。
handleSelect=(item)=>{
        console.log(item)
        this.setState({
            msg:item,
            changeBorder:item.id,
            title:item.title,
            author:item.author,
            digest:item.digest,
            content:item.content,
        })
    }

handleGetTitle=(e)=>{     //與Input標簽之間進行雙向綁定
        this.setState({
            title:e.target.value,
        })
        this.state.msg.title=e.target.value;    //使得輸入框與當前選定的文本框綁定
    }

<Input  onChange={this.handleGetTitle} id={this.state.msg.id} value={this.state.title} placeholder="請輸入標題"/>

antd圖片上傳

//判斷用戶上傳文件的格式,不符合提醒用戶,符合則返回true
function beforeUpload(file) {
  if(file.type!=='image/png'&&file.type!=='image/jpeg'&&file.type!=='image/jpg'&&file.type!=='image/gif'){
    message.error("上傳失敗!僅支持jpeg,png,jpg,gif圖片格式");
    return false;
  }else if(file.size/1024/1024>4){
    message.error("上傳失敗!僅支持大小在4M以內的圖片上傳");
    return false;
  }
  return true;
}

//上傳圖片接口
    UploadImg=()=>{
      let self= this;    
      return {
        name: 'media',
        action: `  `,  //這里寫服務器地址
        headers: {    //設置請求頭
          token: cookie.load('usertoken'),
        },
        onChange(info) {
          self.setState({
            uploadWaiting:true
          })
          if (info.file.status !== 'uploading') {
            console.log(info.file, info.fileList);
            self.setState({
              uploadWaiting:false,
            })
          }
          if (info.file.status === 'done') {
            message.success(`${info.file.name}上傳成功!`);
            self.setState({
              uploadWaiting:false,
            })
            self.getData()
          } else if (info.file.status === 'error') {
            message.error(`${info.file.name}上傳失敗!`);
            self.setState({
              uploadWaiting:false,
            })
          }
        },
      }
    }

    <Upload {...this.UploadImg()} beforeUpload={beforeUpload}><Button>上傳圖片</Button></Upload>

列表數據相關操作(table)

constructor(props){
        super(props);
        this.columns=[
            {title:"",
            dataIndex:"ticket",
            width:66,
            render:(record)=>(<img src={record} width="50px" alt="" />)    
            },
            {title:"產品名稱",dataIndex:"name"},
            {title:"產品類型",dataIndex:"type", render(a, productlist, index){
                return <span>{productist.type || "無"}</span>
            }},
            {title:"對應編碼",dataIndex:"keyword"},
            {title:"生產時間",dataIndex:"createtime"},
            {title:"到期時間",dataIndex:"expiretime",render(a,productlist,index){
                let date=new Date(new Date(productlist.expireTime).getTime());
                let nowdate=new Date(new Date().getTime());
                var overtime=<span className="text-danger">已過期</span>;
                var forevertime=<span className="text-success">永不</span>
                var times=`${date.getFullYear()}-${date.getMonth() + 1<10?"0"+(date.getMonth()+1):date.getMonth()+1}-${date.getDate()<10?"0"+date.getDate():date.getDate()} ${date.getHours()<10?"0"+date.getHours():date.getHours()}:${date.getMinutes()<10?"0"+date.getMinutes():date.getMinutes()}:${date.getSeconds()<10?"0"+date.getSeconds():date.getSeconds()}`
                return <span>{productlist.mode===1?(date<nowdate?overtime:times):forevertime}</span>
            }},
            {title:"操作",
            dataIndex:"operation",
            key:"operation",
            width:225,
            render:(a, qrcodelist, index)=>{
                return <span>
                    <a href="# " className="mr-10px" onClick={()=>{this.copyLink(qrcodelist)}}>復制鏈接</a>
                    <a href={`${productlist.ticket}`} target={"_blank"} download={`${productlist.name}`} className="mr-10px">下載產品</a>
                    <Link to={`/index/setting/product/product-edit/${productlist.id}?id=${productlist.id}`} className="mr-10px">編輯</Link>
                    {productlist.mode===2 ? <a href="# "  onClick={()=>{this.showModal2(productlist)}}>刪除</a> : <a href="# " onClick={() => {this.extendProduct(productlist)}}>延時上架</a>}
                </span>
            }
            
        },
        ];
        this.state={
            visible:false,
            visible2:false,
            productlist:[],
            filter: {
                isloading: false,
                name:"",
                total: 0,
                page:1,
                pageSize:20,
            }
        }
        
    }


<Table 
  columns={this.columns} 
  dataSource={this.state.productlist} 
  rowKey={record=>record.id}    //表中的每個記錄應該有唯一的“key”支持,或者將“rowKey”設置為唯一的主鍵,否則會報錯。這里是給表格設置rowKey
  pagination={{onChange:this.onChangePage, current: this.state.filter.page, pageSize: this.state.filter.pageSize , total: this.state.filter.total }} /> 

注意:這里涉及到兩種render寫法,兩種寫法的this指向不同,其他效果差不多
1、render:(a,b)=>{
            let time=a,
            let overtime=b,
            return <div>......</div>
       }
2、render(a,b){
        let time=a,
        let overtime=b,
        return <div>......</div>
    }
                        

滾動監聽及回到頂部

state={
    backTop:false,
    backTopShow:false,
}

componentWillMount=()=>{
        window.addEventListener("scroll",this.handleScroll,true)    //滾動監聽
    }

handleScroll=()=>{
        if(document.documentElement.scrollTop>1000){
            this.setState({
                backTopShow:true,    //當滾動到距離頂部1000px的距離時,“回到頂部”按鈕顯示
            })
        }else{
            this.setState({
                backTopShow:false,
            })
        }
        if(document.documentElement.scrollTop===0){   //當滾動到 0時,清除定時器
            clearInterval(this.scrollTimes)
        }
    }

backToTop=()=>{
        if(document.documentElement.scrollTop>0){
            this.scrollTimes=setInterval(()=>{
                document.documentElement.scrollTop=document.documentElement.scrollTop-60;
            },5)
        }
    }


{this.state.backTopShow?<Button onClick={this.backToTop}>回到頂部</Button>:null}    //“回到頂部”按鈕

關於接口調用函數的寫法

間接調用,被動觸發式用這種寫法,這種寫法用onClick等主動觸發可能會引起Cannot read property 'setState' of undefined錯誤
async userInfoGet(){
        let res=await api.getUserInfo()
        if(res.code===0){
            this.setState({
                userNickname:res.data.nickname
            })
        }else{
            console.log(api.stateCode[res.code]);
        }
    }
componentWillMount(){
    this.userInfoGet()
}  //在別的函數里間接觸發
直接調用,主動觸發式如onClick等,用這種寫法
userInfoGet=async()=>{
        let res=await api.getUserInfo()
        if(res.code===0){
            this.setState({
                userNickname:res.data.nickname
            })
        }else{
            console.log(api.stateCode[res.code]);
        }
    }
<Button onClick={this.userInfoGet}></Button>  //主動調用

將React.Component外部的代碼移入到其內部

外部:
const props = {
  name: 'file',
  action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
  headers: {
    authorization: 'authorization-text',
  },
  onChange(info) {
    if (info.file.status !== 'uploading') {
      console.log(info.file, info.fileList);
    }
    if (info.file.status === 'done') {
      message.success(`${info.file.name} file uploaded successfully`);
    } else if (info.file.status === 'error') {
      message.error(`${info.file.name} file upload failed.`);
    }
  },
};

export default class Demo extends React.Component{}

內部:
export default class Demo extends React.Component{
    state={}
    pluginZipUpload=()=>{
        let self=this;    //這里改動 let self=this
        return{   //這里改動return
            name: 'plugin',
            action: "https://www.mocky.io/v2/5cc8019d300000980a055e76",
            headers:{
                authorization: 'authorization-text',
            },
            onChange(info) {
              if (info.file.status !== 'uploading') {
                console.log(info.file, info.fileList);
              }
              if (info.file.status === 'done') {
                self.setState({
                    pluginAddFile:Object.assign(self.state.pluginAddFile,{     //這里this換成self
                        plugin: info.file.originFileObj
                    })
                })
                console.log(self.state.pluginAddFile.plugin)
              } else if (info.file.status === 'error') {
                message.error(`${info.file.name}上傳失敗`);
              }
            },
        }
      };

}

如何知道函數里需要傳幾個參數或者判斷函數里有幾個參數

es5里可以用arguments打印
es6里可以用拓展運算符...a方法
在函數里寫入...params
handleUpload=(...a)=>{}
console.log(...a)即可打印出來里面需要的參數

可搭配debugger使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM