phantomjs을 dockernize할 때 아래와 같이 fontconfig, freetype을 설치한다해도

RUN yum install -y fontconfig fontconfig-devel freetype freetype-devel libstdc++ ; yum clean all



영문이 깨지는 경우가 있다. 이 때는 다음 패키지를 설치해야 영문이 제대로 출력된다. 

urw-fonts

Posted by '김용환'
,

(자바스크립트/웹 초짜의 슬픔)



https://github.com/visionmedia/superagent/issues/1091



set-cookie(response header 값)는 react/javascript에서 핸들링할 수 없다. 


오직 content-type header만 볼 수 있는 것 같다. 그래서 처음 custom 인증(또는 jwt)할 때는 header가 아닌 response로 결과를 받아야 되요.


즉 cookie는 브라우져에서 처리하는 구조라 자바스크립트에서는 request를 자유자재로 핸들링을 못하는 구조였다.



Posted by '김용환'
,


foreach 문에 함수를 사용해 주어진 매개변수의 속성을 접근해서 배열에 저장(push) 할 때 

아래처럼 속성을 접근할 때 점(.)을 사용하면 에러가 발생한다.



var items = []

logs.forEach(function (item, index) {

                items.push({

                    'id' : item.timestamp

                })

});



이럴 때는 [,]을 사용해 속성을 접근하는 방법이 있고 에러는 발생하지 않는다.



var items = []

logs.forEach(function (item, index) {

                items.push({

                    'id' : item['timestamp']

                })

});




즉 다음 2개는 동일하다.


item.timestamp = '111';


item['timestamp'] = '111';



Posted by '김용환'
,


string(object) 타입을 Boolean 값으로 변환하고 싶을 때. 다음과 같이 사용한다.


var a = Boolean(aaaa);








Posted by '김용환'
,



ES5에서는 require, ES6에서는 import를 사용한다.


import PropTypes from 'prop-types'; // ES6

var PropTypes = require('prop-types'); // ES5 with npm

Posted by '김용환'
,



react를 처음 해보는 개발자라면 인터넷에서 create-react-class를 봤을 것이다.


이게 15.5 이하에서 사용하던 부분인데. 15.6부터 바뀌었다. 



나는 react 16부터 개발하다 보니 소스 코드를 참조하려다가 react 15를 공부한 경우이다.




react 15.6부터는 create-react-class를 사용하면 deprecated warning 로그를 보게 될 것이다. 16.x부터는 삭제된다는 로그가 나온다. 


Warning: Accessing createClass via the main React package is deprecated, and will be removed in React v16.0. Use a plain JavaScript class instead. If you're not yet ready to migrate, create-react-class v15.* is available on npm as a temporary, drop-in replacement. For more info see https://fb.me/react-create-class




예전 코드라고 보고 정리하는 것이 좋다.


ES6의 React.Component로 사용하는 것이 최신 트렌드이다.



https://reactjs.org/docs/react-without-es6.html


https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-react.createclass







예를 들어 아래와 creactReactClass가  React.Component를 상속한 형태로 변경된 것을 볼 수 있다. 



var
createReactClass = require('create-react-class'); var Greeting = createReactClass({ render: function() { return <h1>Hello, {this.props.name}</h1>; } });

=>

class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}








https://github.com/seatgeek/react-infinite/blob/7efd66437b5b01b28d21a35736fa2d8155605b9a/README.md#in-the-browser


아래와 같은 예제 코드는 다음 예제로 변경할 수 있다. 



var createReactClass = require('create-react-class');

var ListItem = createReactClass({
    render: function() {
        return <div className="infinite-list-item">
        List Item {this.props.num}
        </div>;
    }
});

var InfiniteList = createReactClass({
    getInitialState: function() {
        return {
            elements: this.buildElements(0, 20),
            isInfiniteLoading: false
        }
    },

    buildElements: function(start, end) {
        var elements = [];
        for (var i = start; i < end; i++) {
            elements.push(<ListItem key={i} num={i}/>)
        }
        return elements;
    },

    handleInfiniteLoad: function() {
        var that = this;
        this.setState({
            isInfiniteLoading: true
        });
        setTimeout(function() {
            var elemLength = that.state.elements.length,
                newElements = that.buildElements(elemLength, elemLength + 1000);
            that.setState({
                isInfiniteLoading: false,
                elements: that.state.elements.concat(newElements)
            });
        }, 2500);
    },

    elementInfiniteLoad: function() {
        return <div className="infinite-list-item">
            Loading...
        </div>;
    },

    render: function() {
        return <Infinite elementHeight={40}
                         containerHeight={250}
                         infiniteLoadBeginEdgeOffset={200}
                         onInfiniteLoad={this.handleInfiniteLoad}
                         loadingSpinnerDelegate={this.elementInfiniteLoad()}
                         isInfiniteLoading={this.state.isInfiniteLoading}
                         >
            {this.state.elements}
        </Infinite>;
    }
});

ReactDOM.render(<InfiniteList/>, document.getElementById('container'));



->


class ListItem extends React.Component {
render() {
return <div className="infinite-list-item">
List Item {this.props.num}
</div>;
}
}

class InfiniteList extends React.Component {
constructor(props) {
super(props)
this.state = {
elements: this.buildElements(0, 20),
isInfiniteLoading: false
}
}

buildElements(start, end) {
var elements = [];
for (var i = start; i < end; i++) {
elements.push(<ListItem key={i} num={i}/>)
}
return elements;
}

handleInfiniteLoad() {
var that = this;
this.setState({
isInfiniteLoading: true
});
setTimeout(function() {
var elemLength = that.state.elements.length,
newElements = that.buildElements(elemLength, elemLength + 1000);
that.setState({
isInfiniteLoading: false,
elements: that.state.elements.concat(newElements)
});
}, 2500);
}

elementInfiniteLoad() {
return <div className="infinite-list-item">
Loading...
</div>;
}

render() {
return <Infinite elementHeight={40}
containerHeight={250}
infiniteLoadBeginEdgeOffset={200}
onInfiniteLoad={this.handleInfiniteLoad}
loadingSpinnerDelegate={this.elementInfiniteLoad()}
isInfiniteLoading={this.state.isInfiniteLoading}
>
{this.state.elements}
</Infinite>;
}
}

ReactDOM.render(
<InfiniteData />,
document.getElementById("container")
);






Posted by '김용환'
,

React를 이해하고 Redux를 사용해야 할 때 


React 컴포넌트를 개발하고 처음으로 Redux 를 사용하려 하는 개발자를 위한 참조 문서


개념에 대한 이해도를 높이고 Provider를 활용할 수 있는 가이드

(기본 소스로 얘를 이용)

https://www.kirupa.com/react/using_redux_with_react.htm



custom 이벤트 데이터를 payload로 전달할 수 있고 connect에 대한 이해를 높이는 가이드

https://lorenstewart.me/2016/11/27/a-practical-guide-to-redux/



mapStateToProps을 이해하는데 도움되는 가이드

https://www.zerocho.com/category/React/post/57b60e7fcfbef617003bf456










Posted by '김용환'
,



superagent(https://github.com/visionmedia/superagent)는 동기 콜이 없다. 


무조건 비동기 콜이다.


따라서 아래처럼 superagent가 동기콜인양 쓰면 state/props 간의 동기 이슈가 발생할 수 있다. 


즉, superagent에서 end 내부가 동작되기 전에 handleResult가 먼저 실행된다. 


superagent.get('/search_log')
.
query(..)
.
retry(2)
.
end((err, res) => {
if (res.ok) { //..
}
else {
//
..
}

}); {this.handleResult()}




따라서. end() 밑에 성공하고 난 이후에 handleResult()를 호출하는 형태로 진행하면 동기 콜과 같은 효과를 얻을 수 있을 것이다. 


superagent.get('/search_log')
.
query(..)
.
retry(2)
.
end((err, res) => {
if (res.ok) { //..
{this.handleResult()}
}
else {
//
..
}

});




Posted by '김용환'
,



react 컴포넌트 안에서 다음처럼 내부 함수끼리 호출할 때 에러가 발생할 수 있다. 

(handleMouseDown은 bind()되어 있다)


handleMouseDown(e) {

   _handleLog()

}


_handleLog() {

..

}






아래와 같이 _handleLog()를 호출할 때 {와 }를 추가하면 문제가 해결된다. 




handleMouseDown(e) {

   {_handleLog()}

}


_handleLog() {

..

}






render() 함수 내에서도 동일하게 사용할 수 있다.

Posted by '김용환'
,

react 컴포넌트간의 통신을 위해 redux 처음 공부할 때 


매우 도움되는 싸이트는 www.kirupa.com이다. 



이 중 연동 부분은 다음과 같다. 


https://www.kirupa.com/react/using_redux_with_react.htm



javascript 프로젝트를 처음을 해보니 react-redux 개발을 끝내고 나니, 저 싸이트가 최고더라는 생각이 들었다. 

Posted by '김용환'
,