728x90
반응형


import _ from 'lodash' // https://lodash.com/docs/4.17.15 확인하자 라이브러리
import * as types from '../action/ActionTypes';

const initialState={
    currentMenuName: '',

};


const menuListReducer = (state=initialState, action) => {
    switch (action.type) {
        case types.MENU_ALL_LIST:
            return {
                ...state,
                menuList: action.menuList
          }
        case types.MENU_HR_LIST:
            return {
                ...state,
                menuList: [_.mapKeys(action.menuList, 'menuCode').HR00]
          }
        case types.MENU_ACCOUNT_LIST:
            return {
                ...state,
                menuList: [_.mapKeys(action.menuList, 'menuCode').ACC00]
          }
        case types.MENU_LOGI_LIST:
            return {
                ...state,
                menuList: [_.mapKeys(action.menuList, 'menuCode').LOGI00]
          }
        default:
            return state;
    }
}
export default menuListReducer;


728x90
반응형
728x90
반응형

문자열 병합

배열의 문자열 요소들을 몇몇 구분자로 합치려할 때 사용하며, 매개변수가 생략됐을 때의 기본값은 쉼표이며,

정의 되지않은 요소, 삭제된 요소는 모두 빈 문자열로 취급한다

const array15 = [1, null, "hello", "world", true, undefined];

delete array15[3];

array15.join(); // "1,,hello,,true,"

array15.join(''); // "1hellotrue,"

array15.join(' -- '); // "1 -- -- hello -- -- true --"

 

 

// 문자열 병합과 Array.prototype.join을 함께 쓰면 HTML<ul> 리스트 같은 것도 만들 수 있다

const attributes = ["Nimble", "Perceptive", "Generous"];

const html = '<ul><li>' + attributes.join('</li><li>') + '</li></ul>';

// html : "<ul><li>Nimble</li><li>Perceptive</li><li>Generous</li></ul>";

 

 

Object.keys

객체에서 나열 가능한 문자열 프로퍼티를 배열로 반환

const o = { a : 1, b : 2, c : 3, [SYM] : 4 };

const SYM1 = Symbol();

Object.keys(o)

.forEach(prop => console.log(`${prop} : ${o[prop]}`)); // “a : 1“ “b : 2“ “c : 3“

.filter(prop => prop.match(/^x/)); // “a : 1“ “b : 2“ “c : 3“ []

// 이 예제는 for...in 루프를 썻을 때와 같은 결과이고 hasOwnProperty()를 체크할 필요가 없다

// 객체의 프로퍼티 키를 배열로 가져와야 할 때는 object.keys가 편리하다

 

 

for...in

객체 프로퍼티를 나열할 때 for...in을 주로 사용했다

const SYM = Symbol();

const o = { a : 1, b : 2, c : 3, [SYM] : 4 };

for(let prop in o){

if(!o2.hasOwnProperty(prop)) continue;

console.log(`${prop} : ${o2[prop]}`);

}

for...in을 배열에 사용할 수도 있겠지만, 그리 좋은 생각은 아니다.

배열에는 일반적으로 for루프나 forEach를 사용

 

 

forEach(callback, thisArg)

for문과 마찬가지로 반복적인 기능을 수행할 때 사용한다 하지만 for문 처럼 index, 조건식, 증감식이 필요없다

callback 함수를 통해 그 기능을 대신하며 callback 함수내에 조건문으로 다른 배열을 만들수 있다

 

const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

array.forEach(function(element, index, array){

console.log(`${array}의 ${index}번째 요소 : ${element}`);

});

//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10의 0번째 요소 : 0 콜백 함수의 첫 번째 매개변수는 배열의 요소를 차례로 받아오며,

//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10의 1번째 요소 : 1 두 번째는 인덱스 넘버, 세 번째는 배열의 변수가 할당된다

 

for...of

for(let face of hand)

console.log(`you rolled...${face}!`); // 템플릿 문자열 - 문자열과 ${ }를 통해 값을 삽입할 수 있다

// for...of 배열에 루프를 실행해야 하지만 각 요소의 인덱스를 알 필요는 없을 때 알맞다

 

 

728x90
반응형
728x90
반응형

배열 push(), pop(), unshift(), shift()

배열의 처음이나 끝에서 요소 하나를 추가하거나 제거하고 나머지를 변수에 저장한다

const array2 = ["b", "c", "d"];

 

const a9 = array2.push("e"); 배열의 요소 "e"가 마지막 배열 인덱스에 추가되고 배열길이 값을 a9에 저장된다

 

const a8 = array2.pop(); "e"는 변수 a8에 저장되고 마지막 배열인 "e"가 제거된다

 

const a7 = array2.unshift("a"); 배열 요소 "a"가 제일 첫 배열 인덱스에 추가하고 배열길이 값을 a7에 저장된다

 

const a6 = array2.shift() "a"는 변수 a6에 저장되고 첫번째 배열인 "a"가 제거된다

 

728x90
반응형
728x90
반응형

배열의 끝에 여러 요소 추가하기 concat()

concat 메서드는 배열의 끝에 여러 요소를 추가한 사본을 반환한다

 

const array3 = [1, 2, 3];

const a5 = array3.concat(4, 5, 6); 

const a4 = array3.concat([4, [5, 6]]);

 

변수 a5에 두개의 문자열을 합쳐서 저장하고 array3의 원본값은 변경되지 않는다

배열에 배열을 묶어 합치게 되어 [1, 2, 3, 4, [5, 6]] 사본이 a4에 저장된다

 

728x90
반응형
728x90
반응형

배열 일부 가져오기 slice()

 

const array4 = [1, 2, 3, 4, 5];

const b3 = array4.slice(1,3);

 

변수 b3에 array4 배열 인덱스 1부터 3까지 요소를 저장하고 원본은 변동이 없다

첫 번째 매개변수 어디서 부터 가져올지 정하며 두번째는 어디까지 가져올지를 정한다

 

728x90
반응형
728x90
반응형

splice() 임의의 위치에 요소 추가하거나 제거하기

const array5 = [1, 3, 5, 7];

const b4 = array5.splice(1, 2);

 

매개 변수 첫번째 값은 배열의 인덱스 넘버부터 두 번째 인자값의 숫자만큼 요소를 제거한다

제거하고 남은 변수 b4에 저장한다 이 예제에서는 [3, 5]이다

(매개변수 세번재, 네번째는 추가할 요소를 지정할 수 있다)

첫 번째 매개변수 어디서부터 가져올지 정하며 두 번째는 어디까지 가져올지를 정한다

 

 

728x90
반응형
728x90
반응형

특정 값으로 배열채우기 – es6 fill()

배열 생성자 Array와 함께 사용하며 배열의 일부만 채우려 할 때 시작 인덱스와 끝 인덱스를 지정하면된다

 

const array7 = new Array(5).fill(1);

array7.fill("c", 2, 4); array7에 배열 인덱스 번호 2부터 숫자 4개 자리까지 "c"를 채운다

array7.fill(0, -3, -1); array7에 배열 인덱스 번호

 

 

728x90
반응형
728x90
반응형

배열정렬과 역순정렬 sort() reverse()

array4.reverse(); array4는 이제 [5, 4, 3, 2, 1] 입니다

array4.sort(); array4는 이제 [1, 2, 3, 4, 5] 입니다

 

const array8 = [{ name : "Suzanne" }, { name : "Jim" }, { name : "Taervor" }, { name : "Amanda" }];

 

array8.sort((a, b) => a.name > b.name ); array8은 name 프로퍼티의 알파벳 순으로 정렬됩니다.

 

array8.sort((a, b) => a.name[1] < b.name[1] );

array8은 name 프로퍼티의 두번째 글자의 알파벳 역순으로 정렬됩니다

 

 

728x90
반응형
728x90
반응형

배열 검색 - 일치하지 않는 것을 찾지 못하면 –1을 반환한다 

indexOf() lastIndexOf() lastIndexOf()

 

const o9 = { name : "Jerry" };

const array9 = [1, 5, "a", o, true, 5, [1, 2], "9"];

array9.indexOf(5); // 1

array9.lastIndexOf(5); // 5 마지막 인덱스에 가까운 번호가 저장

array9.lastIndexOf(5, 4); // 1 두 번째 매개변수 값은 검색을 끝낼 인덱스 값이다

 

 

findIndex()는 indexOf 보다 더욱 다양한 상황에서 활용할 수 있다

const array10 = [{ id : 5, name : "Judith" }, { id : 7, name : "Francis" }];

array10.findIndex(o => o.id === 5); 0

array10.findIndex(o => o.name === "Francis"); 1

array10.findIndex(o => o === 3); -1

array10.findIndex(o => o.id === 17); -1

배열 검색 메서드

콜백함수를 사용하는 모든 메서드는 호출할 때 this로 사용할 값을 두 번째 매개변수로 받을수 있다

콜백함수 사용시 return 값이 ture인 요소를 찾을 때까지 순회하다가 찾으면 끝이난다

 

find()는 요소 자체를 검색하려할 때

const array10 = [{ id : 5, name : "Judith" }, { id : 7, name : "Francis" }]; json 데이터에 대한 검색

array10.find(o => o.id === 5); { id : 5, name " Juditj" } 요소 자체를 검색이된다

array10.find(o => o.id === 2); undefined

 

const array11 = [1, 17, 16, 5, 4, 16, 10, 3, 49];

array11.find((x, y) => i > 2 && Number.isInteger(Math.sqrt(x))); // 4

 

 

find findIndex에 전달하는 함수의 this도 수정할 수 있다. 이를 이용해서 함수가 객체의 메서드인 것처럼 호출할 수 있다

 

ID를 조건으로 Person 객체를 검색하는 방법의 예제를 확인하자

class Person {

constructor(name){

this.name = name;

this.id = Person.nextId++;

}

}

Person.nextId = 0; Person.nextId 초기값 0을 설정하고 객체가 생성될 때마다

const jamie = new Person("Jamie"); ++증가식이되어 id에 +1씩 된다

juliet = new Person("Juliet");

peter = new Person("peter");

jay = new Person("Jay");

const array17 = [jamie, juliet, peter, jay];

 

 

* 옵션 1 : ID를 직접 비교하는 방법

array17.find(p => p.id === juliet.id); juliet 객체이며, 무명함수를 주로 사용한다 그리고 매개변수 인자값으로

선언되는 것은 배열의 주소를 뜻한다

 

* 옵션 2 : "this" 매개변수를 이용하는 방법

array17.find(function (p){ find() 콜백함수 사용시 return 값이 ture인 요소를

return p.id === this.id 찾을 때까지 순회하다가 찾으면 거기서 끝납니다

}, juliet); juliet 객체

 

728x90
반응형
728x90
반응형

some, every

단지 조건에 맞는 요소가 있는지 없는지 확인만 필요할 때 사용하는 메서드

 

some은 조건에 맞는 요소를 찾으면 즉시 검색을 멈추고 true를 반환하며, 찾지 못하면 false를 반환한다.

 

const array12 = [5, 7, 12, 15, 17];

array12.some(x => x %2 === 0); true; 12는 짝수입니다.

array12.some(x => Number.isInteger(Math.sqrt(x))); false; 제곱근 수가 없다.

 

 

every는 배열의 모든 요소가 조건에 맞아야 true를 반환하여 그렇지 않다면 false를 반환합니다.

every는 조건이 맞지 않는 요소를 찾아야만 검색을 멈추고 false를 반환합니다.

 

const array13 = [4, 6, 16, 32];

array13.every(x => x%2 === 0); true; 홀수가 없습니다.

array13.every(x => Number.isInteger(Math.sqrt(x))); false; 6은 제곱수가 아닙니다.

 

 

728x90
반응형
728x90
반응형

mapfilter * 가장 유용한 메서드이다

map과 filter 메서드는 모두 사본을 반환하며 원래 배열은 바뀌지 않으며 함수로 구성된 배열을 말한다

함수로 구성된 배열이 있는데 프라미스가 필요하다면, 일정한 형식의 배열을 다른 형식으로 바꿔야 한다면,

Map을 사용하기 바랍니다. 아래의 예제를 참고하세요

 

const cart = [{ name : "Widget", price : 9.95 }, { name : "Gadget", price : 22.95 }];

const names = cart.map( x => x.name ); ["Widget", "Gadget"];

const prices = cart.map( x => x.price ); [9.95, 22.95];

const discountPrices = prices.map( x => x * 0.8 ); [7.96, 18.36];

 

 

콜백 함수는 각 요소에서 호출될 때 요소 자체와 요소 인덱스, 배열전체를 매개변수로 받는다

map()는 배열의 정보들을 가지고와서 새로운 문자열을 이나 배열을 만들기에 효율이 높다

그리고 map이 배열의 각 요소를 변형한다

 

 

const items = ["Widget", "Gadget"];

const price = [9.95, 22.95];

const cart = items.map((x, i) => ({ name : x, price : price1[i]}));

 

위의 결과 cart : [{ name : "Widget", price: 9.95 }, { name : "Gadget", price : 22.95 }]

 

객체를 괄호로 감싼 이유는 화살표 표기법에서 객체 리터럴의 중괄호를 블록으로 판단하기 때문

 

아래의 예제와 같이 map와 filter를 결합하면 다양한 일을 할 수 있다

const cards = [];

for(let suit of ['H', 'C', 'D', 'S'])

for(let value = 1; value <= 13; value++)

cards.push({ suit, value });

 

value가 2인 카드

 

 

let valueNumber = cards.filter(c => c.value === 2); c.value값이 2인것을 찾아내어 변수에 저장

cards.filter(c => c.suit === 'D');

cards.filter(c => c.value > 10);

cards.filter(c => c.value > 10 && c.suit === 'H');

 

 

function carToString(c){

const suits = { 'H' : '\u2665', 'C' : '\u2663', 'D' : '\u2666', 'S' : '\u2660' };

const values = { 1: 'A', 11 : 'J', 12 : 'Q', 13 : 'K' };

 

for(let i = 2; i <= 10; i++)

values[i] = i;

return values[c.value] + suits[c.suit];

}

 

 

const k = cards.filter(c => c.value === 2 ).map(carToString);

 

const k1 = cards.filter(c => c.value > 10 && c.suit === 'H').map(carToString);

 

 

 

728x90
반응형
728x90
반응형

splice()

- 특정 시작 인덱스부터 인덱스까지 값을 추가하거나 그 자리에 있는 값을 삭제할 수 있는 메서드

 

- 배열. splice(시작 인덱스, 삭제할 요소의 개수, 추가될 요소들)

 

  • 첫번째 인자인 시작인데스는 배열 요소가 변경될 시작 지점입니다. splice는 특정 위치의 요소를 지정하는 것이 필수라 반드시 첫 번째 인자 값은 배열 길이보다 작아야 유효합니다
  • 두 번째 인자인 삭제할 요소의 개수는 시작 인덱스의 위치부터 삭제하고자 하는 개수만큼 요소를 제거합니다. 이때 해당 요소가 제거됨과 동시에 메서드 호출 결과로 값을 반환합니다
  • 세 번째 인자에 추가될 요소들을 지정하면, 시작 인덱스부터 해당 요소들이 추가됩니다.

 

const fruits = ['melon', 'lemon', 'source', 'apple', 'juice']

fruits.splice(4, 1) // ['melon', 'lemon', 'source', 'apple']

fruits.splice(4, 0, 'grape') // ['melon', 'lemon', 'source', 'apple', 'grape']

fruits.splice(2, 1, 'mandarin', 'strawberry', 'watermelon') 
	// ['melon', 'lemon', 'mandarin', 'strawberry', 'watermelon', 'apple', 'grape']

//결과
// ['melon', 'lemon', 'mandarin', 'strawberry', 'watermelon', 'apple', 'grape']

 

- splice(4, 1)를 실행하면 과일이 아닌 juice 문자열이 추출됩니다.

- splice(4, 0, 'grape')는 삭제할 개수를 지정하지 않아 추출되는 요소가 없습니다. 그러나 세번재인자로 인해 시작 인덱스에 grape 문자열이 추가됩니다.

 

 

배열. indexOf("A")의 활용

- indexOf()는 배열에 해당하는 문자를 찾아서 인덱스 값을 반환한다

- splice와 응용하여 시작인덱스 값을 구할 수 있다

var arr = ["A", "C", "D", "A", "E", "F", "A"];

var arr_splice = arr.splice(1, 3) // 1번부터 3개의 요소 ["C", "D", "A"] 꺼낸다

console.log(arr); // ["A", "E", "F", "A"] console.log(arr_splice) - ["C","D","A"]

arr.splice(arr.indexOf("A"), 1, "a"); // "A"를 찾아서 "a"로 변경한다.

 

 

728x90
반응형
728x90
반응형

배열의 마법사 reduce 매우 중요하다

 

Array 객체의 메소드  reduce는 배열 요소를 순환하면서, 정의된 callback 함수에 의해 단일 값으로 누적시킬 수 있다

reduce 메소드의 형태는 인자로 callback 함수와 초기값을 받는다

첫 번째 callback 함수는 기존과 메소드와 달리 여러 매개변수를 정의 한다

아래와 같이 최대 4개까지 매개변수를 받고,  첫 번째 누적된 값과 현재 요소 값은 필수이다

reduce 메소드가 처음에 실행할 때, 누적된 값은 두번째 인자(초기값)을 할당 받는다

이후에는 배열 순환이 끝날 때까지  callback 함수에서 반환된 값을 재할당된다

 

배열 내 값을 누적시키기

const numArr = [1, 2, 3, 4, 5];

const result  =  numArr.reduce((acc, el) => {

      return acc + el

}, 0);

console.log(result);

결과 15

 

숫자형 값이 나열된 배열 리터럴을 numArr 변수에 대입한다

reduce의 callback 함수 매개변수로, 첫 번째 acc(누적된 값)과 el(현재 요소값)을 정의한다

매개변수로 전달된 acc와  el를 합산하여, callback 함수 결과 값으로 반환한다

이렇게 반환된 값은 reduce로 순환된 다음 요소 차례에서 acc으로 할당되어 전달된다.

즉, return으로 반환된 값은  다음 배열요소의 acc가 된다는 의미이다.

또한, 배열의 모든 요소들을 순환하고 난 마지막 반환값이 바로 reduce 메소드의 결과 값이 된다.

 

초기값으로 숫자 0을 대입한다. 이 초기값은 첫 번째 요소에서는 acc로 대입된다.

따라서 배열의 각 요소를 순환하며 초기값 0부터 각 요소의 값들을 합산하게 되었을 때, 

0 + 1, 1 + 2, 3 + 3, 6 + 4, 10 + 5와 같이 진행된다 

 

 

배열의 마법사 reduce 활용하기

const array = [5, 7, 2, 4];

const sum = array.reduce((a, x) => a += x, 0);

 

위의 예제를 자세히 해석해봅시다

1. 첫 번째 배열 요소 5에서 (익명) 함수를 호출한다. a의 초깃값은 0이고 x의 값은 5이다.

함수는 a와 x(5)의 합을 반환한다 이 값은 다음 단계에서 a의 값이 된다

2. 두 번째 배열 요소 7에서 함수를 호출한다. a의 초깃값은 이전 단계에서 전달한 5이고

x의 값은 7이다 함수는 a와 x의 합 12를 반환한다 이 값은 다음 단계에서 a의 값이 된다.

3. 세 번째 배열 요소 2에서 함수를 호출한다. 이 단계에서 a는 12이고 x는 2이다.

함수는 a와 x의 합인 14를 반환한다

4. 네 번째이자 마지막 배열 요소인 4에서 함수를 호출한다. a는 14이고 x는 4이다.

함수는 a와 x의 합인 18을 반환하며 이 값은 reduce의 값이고 sum에 할당되는 값이다.

 

reduce는 보통 숫자나 문자열 같은 원시 값을 누적값으로 사용하지만, 객체 또한 누적값이 될수 있다

이를 통해 아주 다양하게 활용할 수 있다는 것을 간과하지 말지 말자 아래의 예제를 보자

 

const words = ["Beachba111", "Rodeo", "Angel", "Aardvark", "Xylophone", "November", "Chocolate",

"Papaya", "Uniform", "Joker", "Clover", "Bali"];

 

const alphabetical = words.reduce((a, x) => {

if(!a[x[0]]) a[x[0]] =[];

a[x[0]].push(x); 

return a; 

}, {}); 

 

배열의 문자열 한글자에 인덱스 넘버 0부터 시작된다

if(![a[x[0]])의 뜻은 첫 번째 배열의 첫 번째 요소가 있는지 확인하는 것이다

a[x[0]]는 "Beachba111"의 B를 찾아 그 이름으로 배열을 저장한다

거기에 push()로 x를 a[x[0]]에 저장한다 그렇게 되면 결과적으로 B : "Beachba111"되고

a를 리턴하여 alphabetical에 저장되어 중첩되고 words 배열에 요소가 없으면 끝이 난다

두번째 매개변수의 뜻은 {}에 기본 값을 설정하는 한다는 뜻이다

 

reduce는 통계에서도 사용할 수 있다. 예를 들어 데이터 셋의 평균과 분산을 계산한다고 생각해보자 아래의 예제를 보자

const data = [3.3, 5, 7.2, 12, 4, 6, 10.3];

const stats = data.reduce((a, x) => {

a.N++; 수학적 공식이라서 그냥 활용방법만 확인하자

let delta = x - a.mean;

a.mean += delta/a.N;

a.M2 += delta * (x - a.mean);

return a;

}, { N : 0, mean : 0, M2 : 0 }); -> 초기값을 설정합니다

if(stats.N > 2){

stats.variance = stats.M2 / (stats.N -1);

stats.stdev = Math.sqrt(stats.variance);

}

 

reduce의 유연성을 알아보기위해 예제를 더 살펴 보자

const longWords = words.reduce((a, w) => w.length > 6 ? a +" "+ w : a, "").trim();

logWords : Beachball Aardvark Xylophone November Chocolate Uniform

 

 

728x90
반응형
728x90
반응형

 

삭제되거나 정의되지 않은 요소들

Array 메서드는 삭제되거나 정의되지 않는 요소들을 다룰 때 쫌 당혹스럽게 동작하곤 한다

 

const array = Array(10).map((x) => 5); 이렇듯 array 요소는 전부 undefined이다 이와 비슷하게

배열 중간의 요소를 삭제하고 map을 호출하면 배열 가운데 undefined가 생긴다

const arr4 = [1, 2, 3, 4, 5];

delete arr4[2];

arr4.map(x => 0); // [0, 0, undefined, 0, 0];

 

일반적으로 배열을 다룰때는 정의된 배열을 다루고, 의도적으로 배열안에 빈 부분을 만든다 하더라도 delete를 사용하지 않는다

그래서 현실적으로 이런 동작이 문제를 일으킬 가능성은 거의 없다 하지만 알아서 나쁠 것은 없으니 알아두자

 

 

728x90
반응형
728x90
반응형

Clipboard Events

이벤트 이름 :onCopy onCut onPaste

속성 : DOMDataTransfer clipboardData

 

 

Composition Events

이벤트 이름 : onCompositionEnd onCompositionStart onCompositionUpdate

속성 : string data

 

 

Keyboard Events

이벤트 이름 :onKeyDown onKeyPress onKeyUp

속성 :

boolean altKey

number charCode

boolean ctrlKey

boolean getModifierState(key)

string key

number keyCode

string locale

number location

boolean metaKey

boolean repeat

boolean shiftKey

number which

이 key속성은 DOM Level 3 Events spec에 설명 된 값 중 하나를 사용할 수 있습니다 .

 

 

Focus Events

이벤트 이름 :onFocus onBlur

이러한 포커스 이벤트는 폼 요소뿐만 아니라 React DOM의 모든 요소에서 작동합니다.

속성 : DOMEventTarget relatedTarget

 

 

Form Events

이벤트 이름 : onChange onInput onInvalid onSubmit

onChange 이벤트에 대한 자세한 정보는 양식을 참조하십시오 .

 

 

Mouse Events

이벤트 이름 :

onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit

onDragLeave onDragOver onDragStart onDrop onMouseDown onMouseEnter onMouseLeave

onMouseMove onMouseOut onMouseOver onMouseUp

 

onMouseEnter및 onMouseLeave이벤트는

하나가 아닌 일반 버블의 입력되는 왼쪽이 되는 요소로부터 전파하고 캡처 단계가 없습니다.

속성 :

boolean altKey

number button

number buttons

number clientX

number clientY

boolean ctrlKey

boolean getModifierState(key)

boolean metaKey

number pageX

number pageY

DOMEventTarget relatedTarget

number screenX

number screenY

boolean shiftKey

 

 

Pointer Events

이벤트 이름 :

onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture

onLostPointerCapture onPointerEnter onPointerLeave onPointerOver onPointerOut

onPointerEnter및 onPointerLeave이벤트는 하나가 아닌 일반 버블의 입력되는 왼쪽되는 요소로부터 전파하고 캡처 단계가 없습니다.

 

속성 :

W3 spec에 정의 된대로 포인터 이벤트 는 다음 속성을 사용하여 마우스 이벤트 를 확장 합니다.

number pointerId

number width

number height

number pressure

number tangentialPressure

number tiltX

number tiltY

number twist

string pointerType

boolean isPrimary

브라우저 간 지원에 대한 참고 사항 :

포인터 이벤트는 모든 브라우저에서 아직 지원되지는 않습니다

(이 기사를 작성할 당시 지원되는 브라우저에는 Chrome, Firefox, Edge 및 Internet Explorer가 포함됨).

표준 준수 폴리 필이의 번들 크기를 크게 늘리기 때문에

React는 의도적으로 다른 브라우저에 대한 지원을 폴리 필하지 않습니다 react-dom.

응용 프로그램에 포인터 이벤트가 필요한 경우 타사 포인터 이벤트 폴리 필을 추가하는 것이 좋습니다.

 

 

Selection Events

이벤트 이름 : onSelect

 

 

Touch Events

이벤트 이름 : onTouchCancel onTouchEnd onTouchMove onTouchStart

속성 :

boolean altKey

DOMTouchList changedTouches

boolean ctrlKey

boolean getModifierState(key)

boolean metaKey

boolean shiftKey

DOMTouchList targetTouches

DOMTouchList touches

 

 

UI Events

이벤트 이름 : onScroll

속성 :

number detail

DOMAbstractView view

 

 

onScroll

이벤트 이름 : onWheel

속성 :

number deltaMode

number deltaX

number deltaY

number deltaZ

 

 

Media Events

이벤트 이름 :

onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted

onEnded onError onLoadedData onLoadedMetadata onLoadStart onPause onPlay

onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend

onTimeUpdate onVolumeChange onWaiting

 

 

Image Events

이벤트 이름 :onLoad onError

 

 

Animation Events

이벤트 이름 : onAnimationStart onAnimationEnd onAnimationIteration

속성 :

string animationName

string pseudoElement

float elapsedTime

 

 

Transition Events

이벤트 이름 : onTransitionEnd

속성 :

string propertyName

string pseudoElement

float elapsedTime

 

 

Other Events

이벤트 이름 :onToggle

 

 

728x90
반응형
728x90
반응형

* GitHub 사용법

  (git을 사용하는 GUI가 존재한다. 이것을 사용하면 직관적인 트리구조로 SVN 사용하듯이 사용할 수 있다)

1) Start a project 클릭 (GitHub 웹페이지 들어가서 버튼클릭)

 

2) 저장소를 만드는 단계

(필수)Repository name : 저장소의 이름, 사용자가 원하는 이름 입력

(선택)Description : 선택 입력으로 저장소에 대한 설명(주석)

(필수)Public, Private : 무료 계정인 경우 Public만 사용 가능, 개인 저장소를 원한다면 결제를 해서 Private 사용.

(선택)Initialize this repository with a README :

저장소 생성과 함께 README 파일이 설치된다.(README 파일은 코드의 정보가 담겨있다)

(선택)Add .gitignore : 깃 허브로 올리지 않을 파일 선택

(선택)Add a license : 저장소 생성과 함께 라이센스 파일의 설치가 자동 수행된다.

 

필수 사항만 입력 후 Create repository 클릭

 

3) 저장소가 만들어졌다. 이제 빨간 네모 박스가 깃 저장소의 주소가 된다. 해당 주소를 복사해두자.

 

4) 로컬저장소 생성

이 폴더는 깃 저장소의 주소와 연동이 되며 깃 주소는 원격 저장소가 되고 해당 폴더는 로컬 저장소가 된다.

☞ git init [My project name] -- 새로운 로컬 저장소를 생성하기 (cmd창의 현재경로에서 폴더를 생성하게 된다)

 

5) 로컬 저장소에서 아래 명령어를 입력한다. (해당 주소는 3)에서 만들어진 저장소의 주소이다)

* 우리가 만든 GitHuB의 웹 주소가

☞ git clone [url]

☞ git clone https://github.com/Szhyun/selfstudy.git

명령어가 실행되면 warning이 뜨는데 해당 에러는 저장소가 비어있다는 의미이다.

하지만 새로 저장소를 만든 상황이기 때문에 에러는 신경쓰지 않아도 된다.

 

6) 4)에서 만든 폴더로 이동해보면 아래와 같이 우리가 만들었던 저장소의 이름으로 폴더가 생성되어있는 것을

확인할 수 있다. (selfstudy 폴더안에 숨긴파일로 .git폴더가 있다면 성공)

 

9) 이제 깃허브로 어떻게 버전 관리를 하며 반영이 되는지 알아보자.

현재 특정 프로젝트 진행 중인 몇 개의 파일을 추가했다.

cmd창에서 로컬 저장소로 접속한다.

 

10) 로컬 저장소에서 git status 명령어 입력 (git status 명령은 파일의 상태를 확인)

☞ On branch master : branch는 깃 사용의 좀 더 심화된 개념으로 지금은

master라는 브랜치에서 작업중이구나 정도로 이해하면 된다.

 

파일을 추가하거나 변경한 파일은 아래와 같이 빨간 글씨로 표시된다.

 

12) 로컬 저장소에서 git add * 명령어 입력

위의 파일들을 원격 저장소로 올려주는 작업이 필요하다. 그러기 위해서는 먼저 로컬 저장소에서 어떤 파일을 커밋할 것인지 찾는 작업이 우선이다.(Untracked 상태의 파일을 Tracked 상태로 만드는 작업)

 

git add * 명령어는 모든 파일을 커밋한다는 의미이다.

특정 파일만을 커밋하고 싶다면 git add 파일명 을 하면 된다.

13) 다시 로컬 저장소에서 git status 명령어 입력 커밋할 준비가 되었는지 확인하는 작업이다.

파일명이 초록색으로 바뀌었다면 커밋할 준비가 되었다는 것을 의미한다.

14) 로컬 저장소에서 git commit 명령어 입력

이제 원격 저장소로 다섯 개의 파일을 커밋시켜보자.

만약 아래와 같이 Please tell me who you are. 이라는 에러가 떨어진다면

 

14-1) 깃을 사용하기 위해 기본적으로 이름과 이메일 주소가 필요하기 때문에 사용자 정보를 추가해주면 된다.

아래 명령어 입력

☞ git config user.name "이름 입력"

☞ git config user.email "이메일 입력"

☞ git add *

☞ git commit -m "init"

-m : 커밋시 남길 메시지를 의미한다.

 

15) 커밋 성공시 아래와 같이 files changed가 뜬다.

 

16) 로컬 저장소에서 git push 명령어 입력

마지막으로 커밋한 사항을 원격 저장소에 올리는 작업이다.

git push 명령어를 입력하면 GitHub Login 창이 뜨게 되는데 여기에 자신의 GitHub 아이디와 비밀번호를 입력하면 된다.

 

17) 잠시 기다리면 push 작업이 이루어진다.

 

18) 자신의 깃 저장소에 들어가보면 커밋한 파일이 올라와있는 것을 확인할 수 있다.

로컬 저장소의 파일이 올라왔다면 성공!

위 18) 단계까지가 깃 저장소에 파일을 저장하는 부분이다.

이제 파일을 로컬 저장소에서 수정하고 원격 저장소로 올리는 작업을 해보겠다.

 

19) 우선 나는 로컬 저장소의 5개 파일 중 board_list 파일을 일부 수정했다.

 

20) cmd를 실행하고 로컬 저장소로 접속한다. 아래 명령어를 입력

☞ git status

 

변경된 파일이 빨간 글씨로 표시되어 나타난다.

 

21) 로컬 저장소에서 아래 명령어 입력

☞ git add *

☞ git commit -m "board_list_20181109"

☞ git push

 

22) 원격 저장소, 자신의 깃 저장소로 접속해보자.

아래와 같이 새로 커밋된 board_list_20181109로 코멘트가 달린 파일을 확인할 수 있을 것이다.

파일 목록 위에 2 commits를 클릭해보자.

 

23) 자신이 커밋한 파일의 이력들을 볼 수 있다. 해당 파일 클릭

 

23) 수정된 부분은 아래와 같이 푸른색으로 표시가 되며 해당 라인들의 +버튼을 클릭하면 코멘트를 달 수 있다.

 

여기까지가 로컬 저장소를 이용한 깃의 등록과 수정 사용법이다.

 

 

728x90
반응형

'IT_Web > Project_Setting' 카테고리의 다른 글

SVN 설치 및 사용방법  (0) 2022.09.06
GitHub 설치방법  (0) 2020.03.09
자바 설치 및 환경 설정 스키마 계정생성  (0) 2020.03.09
728x90
반응형

 

* GitHub 설치방법 –필요없음 그냥 setup파일 next하면됨

1) https://gitforwindows.org/ 접속 후 Download

 

2) 다운받은 파일(Git 2.19.1 Setup) 실행

Next 클릭

 

3) 기본 경로를 사용. Next 클릭

 

4) 구성 요소 선택

Addtional icons

- On the Desktop : 바탕화면에 아이콘 추가

Windows Explorer integration

- Git Bash Here, Git GUI Here : 폴더에서 Git에 바로 연결할 수 있는 기능 추가

Git LFS(Large File Support) : 용량이 큰 파일 지원

Associate .git* configuration files with the default text editor : .git 형식의 파일을 기본 텍스트 편집기와 연결

Associate .sh files to be run with Bash : Bash와 함께 실행될 sh 파일 연결

Use a TrueType font in all console windows : 윈도우 콘솔에서 올바른 글꼴 사용여부

Check daily for Git for Windows updates : 매일 업데이트 확인 여부

기본 옵션으로 Next 클릭

 

5) 시작 메뉴에 추가할 폴더를 선택(만들어진 폴더가 없을 경우 자동 생성)

Don't create a Start Menu folder를 체크하면 시작 메뉴에 추가하지 않는다.

기본 옵션으로 Next 클릭

6) Git 편집기를 선택

VimWindowsGit의 기본 편집기로 Next 클릭

 

7) PATH 환경 설정

Use Git from Git Bash only : Git Bash에서 Git command line tools만 사용 가능

Use Git from the Windows Command Prompt : Git BashWindows 명령 프롬프트(cmd)에서 Git 사용 가능

Use Git and optional Unix tools from the Windows Command Prompt : Git과 유닉스 툴을 사용자 PC 경로에 추가해서 Git을 사용

기본 옵션으로 Next 클릭

 

8)HTTPS 선택

Use the OpenSSL library : OpenSSL 라이브러리 사용

Use the native Windows Secure Channel library : Windows 인증서 저장소를 사용하여 유효성 검사

기본 옵션으로 Next 클릭

 

9) 텍스트 파일의 line ending 스타일 선택

Checkout Windows-style, commit Unix-style line endings : 체크아웃은 윈도우, 커밋은 유닉스 스타일 적용

Checkout as-is, commit Unix-style line endings : 체크아웃은 스타일 변환없음, 커밋은 유닉스 스타일 적용

Checkout as-is, commit as-is : 체크아웃, 커밋 스타일 변환 없음

이번 설치는 윈도우 환경이기 때문에 기본 옵션으로 Next 클릭

 

10) Git Bash 터미널 설정

Use MinTTY(the default terminal of MSY52) : MinTTY terminal emulator 사용

Use Windows' default console window : Windows 기본 콘솔 사용

기본 옵션으로 Next 클릭

 

11) 기타 옵션

Enable file system caching : 성능 향상을 위해 파일 시스템 데이터를 메모리에 캐시

Enable Git Credential Manager : WindowsGit 보안 자격증명 저장소를 사용하기 위해 Git Credential Manager 활성화

Enable symbolic links : symbolic links 사용

기본 옵션으로 Next 클릭

 

12) 실험 옵션(?)

Enable experimental, built-in rebase : 기본 제공되는 rebase 사용

Enable experimental, built-in stash : 실험적으로 내장 된 숨김 기능 사용

이 부분은 따로 체크를 하지 않아도 되는 것 같다. Install 클릭

13) 설치 실행

14) 설치 완료

15) 윈도우 키를 눌러서 설치된 폴더 확인

16) cmd 창을 열고(윈도우 키-실행에서 cmd 입력) 아래 명령어 입력

cd/

git version

아래와 같이 뜬다면 설치 성공!

 

 

728x90
반응형

'IT_Web > Project_Setting' 카테고리의 다른 글

SVN 설치 및 사용방법  (0) 2022.09.06
GitHub 사용법  (0) 2020.03.09
자바 설치 및 환경 설정 스키마 계정생성  (0) 2020.03.09
728x90
반응형

파일 설치시 파일구조

dev > db > app > oracle

> eclipse, tomcat, workspace, java

 

 

* 자바설치 (dev 파일안 설치)

1. 자바환경변수 설정 >내컴퓨터 >우클릭 >속성> 고급 시스템 설정 >환경변수>시스템변수 창에 >새로만들기

> 경로는 자바설치된 경로로 설정하기 및 환경변수 이름설정 > path를 편집> 새로만들기

>%환경변수이름%\bin

2. 클래스패스 설정 > 시스템변수창에 > 새로 만들기 > %환경변수이름%\bin

3. 자바확인 cmd창에서 java –version - 끝 -

 

* db 오라클설치 알아서 하기 * 설치시 아뒤 및 비번설정 칸이 나온다

 

 

* 스카마 계정 생성 및 테이블 생성하기

1. sqlplus /nolog -- cmd에서 sqlplus 접속하겠다

2. conn / as sysdba -- 시스템관리자로 접속하겠다

3. create user scott identified by tiger default tablespace system; -- 스키마계정 만들기

   *scott - 아이디 tiger – 비밀번호

4 .grant connect, resource, dba to scott; -- 권한설정

5. conn scott/tiger -- 연결방법

6. alter session set nls_territory='AMERICA'; -- 글자깨짐 방지

7. alter session set nls_language='AMERICAN';

8. @C:\dev\db\app\oracle\scott.sql; -- 스키마 생성방법

9. @C:\dev\db\app\oracle\summit2.sql; -- 기존 sql파일이 있을때만 가능한 방법

- .spl 파일은 스키마계정과 sqlplus 접속이 필요하며, 테이블을 먼저 생성하고 나머지를 insert를 해야한다

- select * from 으로 테이블이 생성되었는지 최종적으로 하자

 

 

* 덤프 파일 테이블 생성하기

- 덤프 파일 익스포트 (현재 어떠한 스키마 계정의 userid정보에 대한 spl정보를 익스포트한다)

C:\) exp userid=아이디/비밀번호 file='C:\파일명.dmp' full=y

 

- 덤프 파일 임포트 (현재 덤프파일의 sql정보를 어떤 스키마 계정의 userid정보로 spl정보를 임포트한다)

1. cmd 에서 sqlplus에서 나온 후, C: 폴더로 이동한 상태에서,

2. imp userid=아이디/비밀번호 file='C:\파일명.dmp' full=y

 

 

* sql developer 설치 및 계정추가하기

계정추가 시 c: > windows > system32 > drivers > etc > hosts

hosts파일을 확인하여 로컬의 ip주소 서버의 ip주소를 확인할 수 있다

 

1. local 경우 - 플러스 버튼 클릭 > 접속이름, 사용자이름 스키마계정 & 비밀번호 설정

> 테스트버튼 클릭하여 상태확인

2. server 경우 – 호스트 이름을 서버 주소 이름으로 변경한다 예:] aws.seoulit.co.kr

 

 

* 이클립스 설치

1. 다운로드 받은 이클립스 파일을 dev 파일에 압출을 풀게되면 설치는 끝

2. workspace 또한 dev에 폴더를 생성하고 거기에 만든다

 

 

* 톰캣 설치 및 설정

1. 코어를 다운받고 톰캣을 실행시켜 설치한다 https://tomcat.apache.org/download-70.cgi

    사용자 비밀번호를 입력하고 java경로는 자동인식함으로 건딜지말고 설치경로만 dev > tomcat 에 설치한다

2. Servers 란에 create a new server를 클릭하고 설정을 진행한다

3. Apache를 선택하고 tomcat을 설치한 버전으로 선택한다

4. dev > tomcat 경로를 지정하여 tomcat을 설정한다 (경로지정 주의)

 

 

* STS(Spring Tool Suit) 플러그인 설치 (스프링 기반의 웹 프로젝트를 생성한다)

Help > Eclipse Marketplace에서 Spring Tool Suite 검색

spring 프로젝트시 sts3 standard

 

 

* 실습 프로젝트 생성 및 설정변경

Spring Legacy Project > Spring MVC Project 로 생성

위의 방법으로 플러그인 STS로 프로젝트를 생성하면

JRE 버전도 맞지 않고 서버 라이브러리도 등록되지 않아 변경해야한다

프로젝트 마우스 우클릭 > Project Facets > java 1.8버전 변경 > 우측창 Runtimes > Apache 체크하여 Apply

pom.xml에서 스프링버전을 최신으로 바꿔준다

 

728x90
반응형

'IT_Web > Project_Setting' 카테고리의 다른 글

SVN 설치 및 사용방법  (0) 2022.09.06
GitHub 사용법  (0) 2020.03.09
GitHub 설치방법  (0) 2020.03.09
728x90
반응형

modules / counter.js

import { createAction, handleActions } from 'redux-actions';

const INCREASE = 'counter/INCREASE'; // action type를 변수에 저장하여 그 변수로 handleActions해준다!

const DECREASE = 'counter/DECREASE';

 

export const increase = createAction(INCREASE); // type이 지정된 변수를 careateAction()메소드를 활요하여 액션함수를 생성한다

export const decrease = createAction(DECREASE); // 이 액션함수는 사용할 클래스 내부에서 dispatch로 사용하게된다

 

const initialState = { // 리듀서

number: 0,

};

const counter = handleActions(

// 첫 번째 파라미터로는 액션에 따라 실행할 함수들을 가진 객체를 넣어주고,

// 두 번째 파라미터로는 상태의 기본 값( initialState )을 넣어준다.

{

[INCREASE]: (state, action) => ({ number: state.number + 1 }),

[DECREASE]: (state, action) => ({ number: state.number - 1 }),

},

initialState,

);

export default counter;

 

CounterContainer / contaiers.js

import React, { useCallback } from 'react';

import { useCallback, useDispatch } from 'react-redux';

import Counter from '../components/Counter';

import { increase, decrease } from '../modules/counter';

 

const CounterContainer = () => {

const number = useSelector(state => state.counter.number);  // mapStateToProps와 같은 기능이다

const dispatch = useDispatch();

const onIncrease = useCallback(() => dispatch(increase()), [dispatch]);

const onDecrease = useCallback(() => dispatch(decrease()), [dispatch]);

// useCallback()으로 최적화를 하여 dispatch되는 리듀스와 액션에 대한 state 객체가 변경이 있을 때만 함수가 재사용된다

// 위의 방법은 react-redux의 함수를 사용한 connect방법이다

 

return (

<Counter number={number} onIncrease={onIncrease} onDecrease={onDecrease} />

);

};

 

export default CounterContainer;

 

728x90
반응형
728x90
반응형

reducers / PostsReducers.js

export default (state = [], action) => {

  switch (action.type) {

    case 'FETCH_POSTS' :

      console.log(action.payload)

      return action.payload;

    default:

      return state;

    }

};

 

reducers / usersReducers.js

export default (state = [], action) => {

switch (action.type) {

case 'FETCH_USERS' :

return [ ...state, action.payload] -- es6문법으로 해체

default: 할당이다

return state;

             //state[]에 action.payload를 추가하고 배열을 만든다

}

};

 

reducers / index.js

import { combineReducers } from 'redux';

import PostsReducers from './PostsReducers';

import usersReducers from './usersReducers';

 

export default combineReducers({

posts: PostsReducers,     // 두개의함수를 가지고와 리덕스를 활용하여 state로 저장한다

users: usersReducers      // 그렇게 combine된 함수들은 react-redux에서 connect해서 활용한다

});

 

 

index.js

import React from 'react';

import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';

import { createStore, applyMiddleware } from 'redux';

import thunk from 'redux-thunk';

 

import App from './components/App';

import reducers from './reducers';

 

const store = createStore(reducers, applyMiddleware(thunk));

// createStore을 하면 store를 생성할 수 있으며 미들웨어인 thunk를 같이 인자값으로 생성하면

// 액션함수를 선언할 때 dispatch가 가능하여 자유롭게 리듀서의 정보를 액션에 맞게 변경할 수 있다

 

ReactDOM.render(           // Privider 컴포넌트에 store을 주면, 그 자식컴포넌트에서 store의 정보들을 편하게 사용이 가능하다

                                                // 이때 중요한 점은 applyMiddleware(thunk)도 같이 넣어주면서 store에 저장하게된다

<Provider store={store}>

<App />

</Provider>,

document.querySelector('#root')

);

// 이번 프로젝트는 redux-thunk를 활용하여 비동기식 처리 방법이다

// Thunk는 특정작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼 것을 의미합니다.

// 그리고 보통의 액션생성자는 그냥 하나의 액션객체를 생성할 뿐이지만 redux-thunk를 통해 만들게 되면 그 내부에서 여러가지 작업을 할 수도 있습니다

 

// 총정리

// react-redux의 Provider로 App를 묶어주면 App에 적용될 태그들은 store의 reducers 정보를 적용할 수 있다

// 적용하려고 하는 클래스를 connect함수로 연결하면 사용할 수 있다

 

// redux는 액션 함수들을 한 번에 묶어주어 리듀서를 만들어주어 관리해준다. 이때 redux의 combineReducers 함수를 사용하여야만 한다

 

Thunk와 Saga의 차이점

두 방식의 가장 큰 차이점을 문장 구조라고 생각을 할 것입니다. 그것이 가장 큰 사실이지만 더 큰 차이점이 존재하는데,

Thunks는 절대로 action에 응답을 줄 수 없습니다.

반면 Redux-Saga는 store를 구독하고 특정 작업이 디스패치 될 때 saga가 실행되도록 유발할 수 있습니다.

 

 

actions / index.js

import _ from 'lodash';

import jsonPlaceholder from '../apis/jsonPlaceholder'

 

export const fetchPostsAndUsers = () => async (dispatch, getState) => {

await dispatch(fetchPosts());

 

// thunk의 장점중 하나는 dispatch를 함수로 할수 있다는 것이다 그렇게 전체적인 fetchPostsAndUsers 를 만들어서  호출하여 fetchPosts(), fetchUser(id) 두개를 dispatch하는 과정에서 데이터를 조작하여 id를 주입하게된다

 

// const userIds = _.uniq(_.map(getState().posts, 'userId'));

// userIds.forEach(id => dispatch(fetchUser(id)));

 

_.chain(getState().posts) // lodash의 chain()를 사용하면 가독성에도 좋다 한번 참조하자

.map('userId')

.uniq()

.forEach(id => dispatch(fetchUser(id)))

.value()

};

 

지금의 문제점은 userid의 중복된 호출이다

이것을 보다 성능을 향상시키기 위해 _.memozie()를 활용하는 것과 각종 중복배열을 제거하고

새로운 배열을 만들어 dispatch한다 위의 코드분석은 아래의 블로그를 참조하자

http://kbs0327.github.io/blog/technology/lodash/ , https://gracefullight.dev/2016/12/25/Lodash-활용법/

_.uniq() 배열의 중복제거,

_.map() 특정 값들의 제 배치,

forEach() 배열 나열

 

// export const fetchUser = id => dispatch => _fetchUser(id, dispatch);

// const _fetchUser = _.memoize(async (id, dispatch) => {

// const response = await jsonPlaceholder.get(`/users/${id}`);

 

// dispatch({ type: 'FETCH_USERS', payload: response.data });

// });

 

그 변수는 매개변수로 지정된 함수와 같은 기능을 하는 동시에 이 함수는 메모리에 저장되어 동일한 인자값을 받을 때에는

네트워크에 거치지않고 자체적으로 메모리에 저장하여 request를 하지 않는다는 것이 장점이다

const getUser(int v){

return " hello world";

}

//const memoizedGetUser = _.memoize(getUser);

//memoizedGetUser(3)

//-> " hello world"

위의 예문처럼 최초 한번 네트워크에 요청하면 로그가 남는다. 하지만 그 다음에는 로그가 남지 않음을 알 수 있다

지금처럼 유저 정보가 반복될 때 네트워크에 요청하지 않고 재사용할 수 있다

 

export const fetchPosts = () => async dispatch => {

console.log(dispatch) // api는 개별적으로 관리를 하고 그것을 접근하는 것은 비동기로 처리하는 것이 중요하다

const response= await jsonPlaceholder.get('/posts');

// 그 이유는 JSX문법으로 태그를 넘겨받고 움직이는 컴퓨터의 실행력과 서버에서

// 데이터를 받아오는 시간차가 있기때문에 동기식으로는 절대 받아올 수 없다

 

dispatch({ type: 'FETCH_POSTS', payload: response.data });

// 그래서 비동기식인 async 와 await을 사용하여야 한다

// dispatch를 하려는 액션을 수동으로 불러낸다.

}; 즉, 액션을 직접적으로 돌려주는 것이 아니라 dispatch를 호출하여 액션 오브젝트를 건네어 주게 된다

 

export const fetchUser = id => async dispatch => {

// redux-thunk의 장점은 액션함수에서도 dispatch를 함수를 사용할 수 있다는 점이다

const response = await jsonPlaceholder.get(`/users/${id}`);

// 그렇게 axios로 비동기화 시켜 받아온 정보를 dispatch시켜 액션과 데이터를 건네줄수 있다

dispatch({ type: 'FETCH_USERS', payload: response.data });

};

// 이 예제를 잘 이용하면 어떠한 정보를 CURD하여 그 정보를 액션 타입에 맞게 행동하는 코드를 작성하면 괜찮을 듯 하다

// 그리고 dispatc메서드에 매개변수를 지정하는데 이때 함수를 지정하여 다른 action 파일에 있는 함수도 호출을 할 수 있게 된다

// https://velog.io/@dongwon2/Redux-Thunk-vs-Redux-Saga를-비교해-봅시다- 여기에 들어가면 상세정보를 얻을 수 있다

 

당연히 밑의 예제처럼 일반적인 action 함수도 사용이가능하다

export const selectPost =()=> {

return {

type: 'SELECT_POST' // 하지만 서버에서 DATA를 가져올때에는 비동기식으로 가져올 것을 생각해야만한다

}

})

 

apis / jsonPlaceholder.js

import axios from 'axios';

 

export default axios.create({

baseURL: 'https://jsonplaceholder.typicode.com'

});              // 단지 api를 보관하기위한 파일여러개의 export해서 사용이가능할 것이다

 

 

 

 

 

components / PostList.js

import React from 'react';

import { connect } from 'react-redux'; // react에서 리덕스로 combined된 state를 사용하기 위해서는 react-redux가 필요하고

// connect 메소드라는 함수로 연결을 해주어야한다

import { fetchPostsAndUsers } from '../actions';

import UserHeader from './UserHeader';

 

 

class PostList extends React.Component {

componentDidMount() {

this.props.fetchPostsAndUsers();

}

renderList(){

return this.props.posts.map(post => {

return (

<div className="item" key={post.id}>

<i className="large middle aligned icon user"></i>

<div className="content">

<div className="description">

<h2>{post.title}</h2>

<p>{post.body}</p>

</div>

<UserHeader userId={post.userId}/>

 

</div>

</div>

);

});

}

 

render() {

return <div className="ui relaxed divided list">{this.renderList()}</div>;

}

}

 

const mapStateToProps = (state) => {

return { posts : state.posts}

}

 

export default connect       // 일반적으로 첫 번째 인자값에는 store의 state를 인수로 받습니다.

mapStateToProps                 // store의 state는 props와 맵핑되는 방식을 만들 객체를 반환하는

                                                             mapStateToProps메서드를 사용한다

{ fetchPostsAndUsers } )(PostList); 

// 두 번째 인자값은 mapDispatchToProps는 dispatch action이 props와 맵핑되는 방식을 만들 유사한 객체를 반환한다

// fetchPostsAndUsers 로 정보를 받아와 componentDidMount에서 fetchPostsAndUsers ()를 실행시켜 액션을 취한다

//두 번째 괄호는 이 정보들을 사용할 클래스명을 쓴다

 

 

 

components / UserHeader.js

import React from 'react';

import { connect } from 'react-redux';

 

class UserHeader extends React.Component {

// componentDidMount() {                             // componentDidMount는 부모태그에서 넘겨주는 state만을 받아서 사용가능하다

// this.props.fetchUser(this.props.userId); // 그 이유는 componentDidMount는 랜더링이 끝나고 나서 처음 한번만 실행되기때문이다

// lodash추가로 DidMount 삭제 // 그래서 지금 한 번 실행될 때 fecthuser을 실행함으로써 액션을 실행하게 되고

그렇게 그 후 데이터를 불러온다

 

render() {

const { user } = this.props;

// const user = this.props.users.find(user => user.id ===this.props.userId);

     이렇게 장문으로 해서 비교해서 id를 찾는 방법이있지만

// 부모에서 받아온 props와 dispatch된 props가 혼동될수 있으니 확인하여야한다

if (!user) { // 그래서 밑에 처럼 connect후 mapstateToprops를 통해 기존 ownProps와 state를 구분해서 작업이 가능하다

return null;

}

 

return <div className="header">{user.name}</div>

}

}

 

const mapStateToProps = (state, ownProps) => {

return { user: state.users.find(user => user.id === ownProps.userId) }; // 참고합시다

}

 

export default connect(mapStateToProps)(UserHeader);

// mapstateProps와 그 fetchuser 함수를 연결함으로써 정보를 userHeader에서 사용이가능

 

 

 

components / App.js

import React from 'react';

import PostList from './PostList';

 

const App = () => { // App은 모든 컴포넌트를 받아 전달하는 의미가 있다

return (

<div className="ui container">

<PostList />

</div>

);

}

 

export default App;

 

 

 

 

 

 

728x90
반응형

+ Recent posts

Powered by Tistory, Designed by wallel