Android攻城獅前端遇坑指南

決定一我的命運的不是能力而是選擇react

1.加快安裝

npm config set registry registry.npm.taobao.orgweb

2.寫代碼過程當中webstorm底部一直閃爍,代碼也提示不了

File->Invalidate Cahes/Restart -> Invalidate and Restart
複製代碼

3.按鈕未點擊自動執行點擊事件

handlerClick = (questionId)=>{
    console.log('我執行了')
}
<button type="button"
   onClick={
    this.handlerClick(question_id)
  }>補習詳情
</button>
複製代碼
handlerClick (questionId){
    console.log('我被點擊了')
}
<button type="button"
   onClick={
    this.handlerClick.bind(this,question_id)
  }>補習詳情
</button>
複製代碼
第一種和第二種是兩種常見的函數定義方法,第一種是箭頭函數,第二種是普通函數。推薦用箭頭函數
  • 避免普通函數this形成的一系列問題,而箭頭函數this指向函數定義的組件
  • 每次刷新組件都會從新執行bind方法,對性能有影響
可是第一種箭頭函數確帶來了奇怪的問題:按鈕未點擊handlerClick函數自動執行了,而不傳參數的話是不會自動執行的,這是爲何?明明看起來兩種寫法差很少!在講這個問題以前咱們首先來看一下匿名函數
function (){
    console.log('我執行了')
}
複製代碼
忽略箭頭函數的內部細節,咱們發現其實箭頭函數就是匿名函數。再來看看匿名函數是如何執行的
function (){
    console.log('我執行了')
})()
複製代碼
聰明的你應該發現問題了,第一種箭頭函數傳參就至關於匿名函數當即執行。講清楚了爲何會當即執行,看下如何解決
<button type="button"
   onClick={()=>{
       this.handlerClick(question_id)
   }
  }>補習詳情
</button>
複製代碼
這有什麼區別?第一種箭頭函數的寫法等價於
onClick=(function(){
    console.log('我執行了') 
})(questionId)
複製代碼

第二種等價於npm

onClick=function(){
    return function handlerClick(questionId){
        console.log('我執行了') 
    }
}
複製代碼
那麼bind爲何不會當即執行?由於bind返回的仍是函數

4.ant Design Select組件的坑

<Select defaultValue={0} onChange={this.handleClasses} className="selectClasses">
   {
   allClass.map((value, index) =>
          <Select.Option value={index}>{value.class_name}</Select.Option>
       )
    }
</Select>
複製代碼
開始allClass是空數組,等到網絡請求返回allClass纔有數據,而後組件會刷新。這時候很奇怪defaultValue沒有刷新,莫名其妙的設置不了默認數據。會出現下圖所示的狀況

下面的寫法能夠避免這種狀況
{
 allClass.length !== 0 ?
   <Select defaultValue={0} onChange={this.handleClasses} className="selectClasses">
    {
      allClass.map((value, index) =>
       <Select.Option value={index}>{value.class_name}</Select.Option>
      )
    }
   </Select> : <div/>
}
複製代碼
這種寫法更優雅
{
 allClass.length !== 0 &&
   <Select defaultValue={0} onChange={this.handleClasses} className="selectClasses">
    {
      allClass.map((value, index) =>
       <Select.Option value={index}>{value.class_name}</Select.Option>
      )
    }
   </Select>
}
複製代碼

5.react.setState()以後不能獲取更新後的數據

下面獲取到的count仍是-1
this.state={
    count = -1
};
this.setState({ count: 0 });
console.log(this.state.count);
複製代碼
實際上setState並不會立馬執行,它會把狀態存到隊列中,稍後纔會更新state的值,下面的寫法能夠避免這種狀況
this.setState({ count: 0 },
() => console.log(this.state.count))
複製代碼

6.本身搞的簡易的react Componet

export default class Component {
    constructor(props = {}) {
        this.props = props;
    }

    setState(state) {
        const oldEl = this.el;
        this.state = state;
        this._renderDOM();
        if (this.onStateChange) this.onStateChange(oldEl, this.el);
    }

    _renderDOM() {
        this.el = this._createDOMFromString(this.render());
        if (this.onClick) {
            this.el.addEventListener('click', this.onClick.bind(this), false)
        }
        ;
        return this.el;
    }

    _createDOMFromString = (domString) => {
        const div = document.createElement('div');
        div.innerHTML = domString;
        return div;
    }
    
    mount = (component, wrapper) => {
        wrapper.appendChild(component._renderDOM());
        component.onStateChange = (oldEl, newEl) => {
            wrapper.insertBefore(newEl, oldEl);
            wrapper.removeChild(oldEl);
        }
    }

    onStateChange(oldEl, newEl) {}

    render() {}

    onClick() {}
}
複製代碼

7.react-router-dom使用

函數方式跳轉傳參
this.props.history.push({
      pathname: '/detail',
      state: {
        id: 3
     }
)

複製代碼

防止重複跳轉死循環redux

this.props.history.replace('/detail');
複製代碼

goBack返回數組

this.props.history.goBack();
複製代碼

8.redux使用,redux用於數據共享

index.js註冊

import counter from './reducers/index';
import {createStore} from 'redux';

const store = createStore(counter);
const render = () =>
    ReactDOM.render(<App
        value={store.getState()}
        onIncrement={() => store.dispatch({type: 'INCREMENT'})}//action
        onDecrement={() => store.dispatch({type: 'DECREMENT'})}
    />, document.getElementById('root'));
render();
store.subscribe(render);
複製代碼
creare函數

export default (state = 0, action) => {
    switch (action.type) {
        case 'INCREMENT':
            return state + 1;
        case 'DECREMENT':
            return state - 1;
        default:
            return state
    }
}
複製代碼
組件

 const {value, onIncrement, onDecrement} = this.props;
 <p>{value}次數拉拉拉</p>
 <button onClick={onIncrement}>加上</button>
 <button onClick={onDecrement}>減去</button>
複製代碼

9.js精度問題

0.07.toFixed()*100 = 7.00000000000000001%
複製代碼
(0.07*100).toFixed() = 7%
複製代碼

好用的js方法

1.正確返回字符串長度
function length(str) {
  return [...str].length;
}
複製代碼

或者bash

function countSymbols(string) {
  return Array.from(string).length;
}
複製代碼

2.判斷一個字符是單字節仍是雙字節網絡

function is32(c){
  return c.codePointAt(0) > 0xFFFFFF;
};
複製代碼

3.正則判斷金額是否正確react-router

let s = "1512.1";
let patter = /^\d+\.?\d{1,2}$/g.test(s);
複製代碼

4.將數組中布爾值爲false的成員轉爲0app

Array.from([1, , 2, , 3], (n) => n || 0)
複製代碼

5.數組去重dom

[...new Set([1,2,3,4,5,2])]
複製代碼

6.去除重複字符串

[...new Set('ababbc')].join('')
複製代碼
相關文章
相關標籤/搜索