Skip to content

devLog[0821] localStorage

Chany edited this page Aug 21, 2018 · 4 revisions

today

요구사항

최근 검색했던 5건의 검색키워드가 아래 노출돼야 한다.
예를들어 '땅콩'을 입력한 후 검색버튼(돋보기)을 누른후에, 다시 웹사이트에 접속하면 최근 검색했던 '땅콩' 키워드가 노출돼야 한다.

  1. 생각해보니 그냥 순서데로 recent를 가지고 오게 했는데 최근 5개만 가지고 오도록 수정해야 한다.

Issue

만두 만두 같은 keyWord는 중복된다. 이런 부분 방지하기 위해서 Set을 써야 하나?

export default class SearchFormModel {
  constructor() {
    this.KeyList = []
  }
  saveKeyWords(data) {
    const Idx = localStorage.length
    const key = `keyword-${Idx}`;
    this.KeyList.push({key: data});
    localStorage.setItem(key, data)
  }
  getKeyWords(){
    const keyPrefix = `keyword-`
    const lastIdx = localStorage.length-1;
    const keyWordCounts = 5;
    
    return [...new Array(lastIdx).keys()].map(i=>localStorage.getItem(`${keyPrefix}${i}`)).slice(lastIdx-keyWordCounts)   
  }
}
2018-08-21 1 07 43

var a = localStorage.getItem('key')
a "[object Set]"
로컬 스토리지는 문자열로 밖에 저장을 못 한다 _= 고로쿠나

  saveKeyWords(data) { 
    let keywordList = this.getLocalItem();
    const keyWordCounts = keywordList.length
    // 중복 방지
    const keywordSet = new Set(keywordList.map(({keyword})=>keyword))
    if(keywordSet.has(data)) return ;
    keywordSet.add(data)
    keywordList = [...keywordSet].map((keyword, id)=>({id, keyword}))
    localStorage.setItem(key, JSON.stringify(keywordList))
  }
//이렇게 수정했는데 가만 생각해보니 중복 체크를 위해서 너무 순회하는 작업이 많은데 
new Set(keywordList.map(({keyword})=>keyword))
keywordList = [...keywordSet].map((keyword, id)=>({id, keyword}))
2번이나  돈다. 
굳이 Set으로 만들어 줘야 하나? 생각해보니 그냥 some으로 검출해서 값이 나오면 바로 return 하면   같다. 

  let keywordList = this.getLocalItem();
    const keyWordCounts = keywordList.length
    // 중복 방지
    const hasSameData = keywordList.some(keywordData=>keywordData.keyword===data)
    if(hasSameData) return ;
    // 저장
    keywordList = [...keywordList, {id: keyWordCounts, keyword: data}]
    localStorage.setItem(this.key, JSON.stringify(keywordList))

이렇게 수정 

네이밍

export const recentKeyWordTemplate = (keywords)=>{
  return keywords.reduce((ac, c) =>(ac += `<li data-id=${c.id}><span>${c.keyword}</span></li>`),``);
}

export const keyWordTemplate = (keywords)=>{
  return keywords.reduce((ac, c, ci) =>(ac += `<li data-id=${ci}><span>${c}</span></li>`),``);
}

export const keyWordListTemplate = (keyword, keywordList) =>{
  const keyWordTempate = keyWordTemplate(keywordList)
  const keywordRegex = new RegExp(keyword, 'gi');
  return keyWordTempate.replace(keywordRegex, `<span class="hl">${keyword}</span>`)
}
네이밍 이거 어떻게 하지 ;;; 
일단 keyWordObjList /keyWordTextListTemplate 이정도로 수정할까 ?;;; 

input Change Event는 React에서 onChange가 계속 받은 걸로 기억해서 왜 event를 계속 못 읽지 했는데 ... focus를 잃었을 때만 한 번 발생한다. 지속적인 감지는 `key up 아니면 change를 통해서 `

issue

  handleKeyup(e){
     const {isComposing} = e
    if(isComposing) this.deBounceKeyEvents(e)
  }
이렇게 하면 근데 지울때 적용이  된다. 
isComposing은 계속 있어야 되나 ? ->  부분이 없애면 debounce로만 ajax통신을 하기 때문에 제대로 값을 읽어 온다 ! 
근데 문제는 up down할  이상현상이 발생한다. 
 그럴까? -> up/ down 키를 받아서 새로 통신했는데 data가 없다. up/down키를 받았을 때는 ajax로 들어가는 부분에서는 바로 return이 일어나도록 수정 하기 
  1. 우선 keyup으로 해결하려면 어떻게 해야 할까?

  2. change써서 해보기

취소 하는 부분 body Click에서 e.target에 따라서 취소할 수 있고 그 target에게 bubbling을 방지하는 e.stopPropagation()을 걸어줄 수도 있다.

검색창 UX 구글이랑 아마존 네이버 비교

1. 구글/아마존 input에 value가 한 글자라도 있으면 최근 검색어 focus될 때 로드가 안된다. 
2. 네이버 같은 경우는 그 글자로 ajax통신해서 글자를 얻어온다. 
3. 구글/아마존 위 아래 키가 모두 적용 되는 네이버  처음에 위에 키를 누르면 바로 닫힌다

위/아래 키는 모두 적용해야 될 것 같고 글자가 있으면 다시 focusing될 때 글 글자로 통신해야 될 것 같다

크롱 리뷰 반영

  • Constructor 객체로 인자 받기

  • 매직넘버 없애기 모둘 위에 const 로 선언하고 가져다 쓰고 최대한 defaultParam도 활용해서 전역 property를 없앤다. 이런 전략을 세웠는데 다른데는 어떻게 하고 있나? 알아보자 !!!

  • {type: 1}

 handleChangeSelected(type){
    this.clearActiveClass(qs(`[data-id="${this.active_KeyWordIdx}"]`, this.keyWordList))
    this.handleChoseActiveIdx(type)

this.handleChoseActiveIdx({type:1})  부분 이해 못함 ;;
어떻게 분기 없이   있는 거지???