1월, 2020의 게시물 표시

[React] React-Redux 정리

mapStateToProps function mapStateToProps ( state ) { return { a : 42 , todos : state.todos, filter : state.visibilityFilter } } // component will receive: props.a, props.todos, and props.filter Copy 위처럼 작성하면 props.a / props.todos / props.filter를 통해 접근할 수 있다. 1. mapStateToProps는 단순히 store에서 state를 가져다 주는 것이 아니라 component가 바로 사용가능하도록 만들어야된다. 2. selector function을 사용할 것 3. mapStateToProps는 store에 변경사항이 있을때마다 호출되기때문에 최대한 빨라야한다. 4. mapStateToProps는 pure하고 synchronous해야된다. mapDispatchToProps const mapDispatchToProps = dispatch => { return { // dispatching plain actions increment: () => dispatch({ type : 'INCREMENT' }), decrement : () => dispatch({ type : 'DECREMENT' }), reset : () => dispatch({ type : 'RESET' }) } } Copy mapDispatchToProps를 사용하면 위에서 언급한 mapStateToProps처럼 props.increment()이런식으로 호출이 가능해진다. React-Redux를 사용하면 store를 직접 접근하는일은 없다. connect(mapStateToProps, mapDispatchTo

[React] Redux 정리

한줄 간단 요약: Redux를 사용하면 state를 바로 바꾸는 것이 아니라 action 이라는 객체를 생성하여 어떤 state를 바꾸고 싶은지를 type 에 명시하여 dispatch 하면, 해당되는 reducer 가 action.type에 따라 state를 변경한다. combineReducer() Reducer의 인자로 넘어오는 state는 현재의 state, action은 dispatcher가 보낸 action 객체이다. combineReducer()는 state에서 key와 이름이 같은 property를 argument로하여 호출해준다. import { combineReducers } from 'redux' const todoApp = combineReducers ( { visibilityFilter , todos } ) export default todoApp 위의 코드는 아래와 같다: export default function todoApp ( state = { } , action ) { return { visibilityFilter : visibilityFilter ( state . visibilityFilter , action ) , todos : todos ( state . todos , action ) } } Copy custom하게 사용하고 싶다면: function reducer ( state = { } , action ) { return { a : doSomethingWithA ( state . a , action ) , b : processB ( state . b , action ) , c : c ( state . c , action ) } }

새로운 개발자를 위한 공부순서

Introduction 본 리스트는 현재 작성되어 있는 코드를 이해하기 위한 최소한 의 리스트이며 공식문서를 읽을때나 코드를 볼때 궁금한점, 혹은 깊이 알아야될 것이 있을 때는 더 찾아보고 공부해야된다. 코드를 이해할 때의 팁: 만약 코드를 볼때 잘 모르겠다면, 일단 해당 코드가 호출되는 곳을 검색해가며 가장 최상단 코드(가장먼저 실행되는)로 이동한다. 최상단 코드가 이해가 되었다면 한단계씩 타고 내려가며 이해하도록 해본다. 만약 코드를 보다가 모르겠다면, 대부분 모르는 라이브러리를 사용하고 있거나 프레임워크를 사용하고 있기 때문이다. 따라서 현재 보고 있는 소스코드의 최상단으로 올라가면 import { ... } from  ' ... '; 구문이 있을텐데 소스코드가 import하고 있는 프레임워크 / 라이브러리의 기능을 구글링해가며 이해하도록 노력한다. 아래에 링크되어 있는 문서들을 읽고나면 대부분은 이해가 되겠지만 굵직한 것들을 최소한을 적은 것으로 부분부분 이해가되지 않는 소스코드들은 이런방식으로 이해하도록 한다. 해당 기능이 어떤 역할을 하고, 어떤 인자를 받으며, 어떤 값들을 반환하는 지를 공식문서를 통해 파악하고 나면 이해하는데 큰 어려움은 없을 것이다. Backend Application Server Django Official Document       - Models and databases              - Models              - Making Queries              - Aggregation              - Search              - Managers     - Handling HTTP requests              - URL dispatcher              - Writing views              - View decorators              - Generic

[React] 8. Lists and Keys

Key는 React가 어떤 아이템들이 변경, 추가, 삭제되었는지 판단할 수 있도록 도와준다. Key를 고르는 가장 좋은 방법은 list의 아이템들이 자신의 sibling들 사이에서 unique하게 판별할 수 있는 값으로 하는 것이 좋다.  대부분의 경우 data의 ID가 사용된다. function ListItem ( props ) { // Correct! There is no need to specify the key here: return < li > { props . value } </ li > ; } function NumberList ( props ) { const numbers = props . numbers ; const listItems = numbers . map ( ( number ) => // Correct! Key should be specified inside the array. < ListItem key = { number . toString ( ) } value = { number } /> ) ; return ( < ul > { listItems } </ ul > ) ; } const numbers = [ 1 , 2 , 3 , 4 , 5 ] ; ReactDOM . render ( < NumberList numbers = { numbers } /> , document . getElementById ( 'root' ) ) ; 가장 쉽게 생각하자면, 만약 map이 사용되었다면, key를 부여해주어야 한다. key는 자신의 sibling들 사이에서만 unique하면되며, global하게 unique할 필요는 없다.

[React] 7. Conditional Rendering

true && expression은 expression을 반환하고, false && expression은 false를 반환하여 무시된다. function Mailbox ( props ) { const unreadMessages = props . unreadMessages ; return ( < div > < h1 > Hello! </ h1 > { unreadMessages . length > 0 && < h2 > You have { unreadMessages . length } unread messages. </ h2 > } </ div > ) ; } const messages = [ 'React' , 'Re: React' , 'Re:Re: React' ] ; ReactDOM . render ( < Mailbox unreadMessages = { messages } /> , document . getElementById ( 'root' ) ) ; Inline If-Else with Conditional Operator render ( ) { const isLoggedIn = this . state . isLoggedIn ; return ( < div > { isLoggedIn ? ( < LogoutButton onClick = { this . handleLogoutClick } /> ) : ( < LoginButton onClick = { this . handleLoginClick } /

[React] 6. Handling Events

Binding render ( ) { return ( < button onClick = { this . handleClick } > { this . state . isToggleOn ? 'ON' : 'OFF' } </ button > ) ; } 위처럼 ()를 붙이지 않고 method를 레퍼런스하는 경우, 메서드를 바인드 해주어야 한다. constructor ( props ) { super ( props ) ; this . state = { isToggleOn : true } ; // This binding is necessary to make `this` work in the callback this . handleClick = this . handleClick . bind ( this ) ; } 이렇게 매번 바인딩해줘야 하는 것이 불편하다면, class LoggingButton extends React . Component { // This syntax ensures `this` is bound within handleClick. // Warning: this is *experimental* syntax. handleClick = ( ) => { console . log ( 'this is:' , this ) ; } render ( ) { return ( < button onClick = { this . handleClick } > Click me </ button > ) ; } } 이렇게 Arrow Function을 사용할 수 있다.

[React] 4. Components and Props

Javascript Function style component function Welcome ( props ) { return < h1 > Hello, { props . name } </ h1 > ; } ES6 class style component class Welcome extends React . Component { render ( ) { return < h1 > Hello, { this . props . name } </ h1 > ; } } render ReactDOM . render ( element , document . getElementById ( 'root' ) ) ; 요렇게 하면 element를 root라는 element 하위로 render하겠다는 것이다. User-defined Component React는 user-defined component를 사용하는 element를 만나면 해당 element의 attribute을 props에 넣어 user-defined component로 전달한다. 그리고 중요한 점은 component의 이름을 지을때 항상 대문자로 시작하도록 해야한다. 소문자로 시작하면 React는 해당 component를 DOM tag로 취급한다. Components should not attempt to modify props!

[React] Tic Tac Toe 과거기록에서 이어서 하기 / Resume from history

React 튜토리얼에서 Tic Tac Toe가 진행되는 과정을 히스토리로 저장하고 돌아갈 수 있는데 이어서 할 수는 없습니다. 이를 보완한 코드입니다. ------------------------------------------- function Square(props) {   return (     <button className="square" onClick={props.onClick}>       {props.value}     </button>   ); } function calculateWinner(squares) {   const lines = [     [0, 1, 2],     [3, 4, 5],     [6, 7, 8],     [0, 3, 6],     [1, 4, 7],     [2, 5, 8],     [0, 4, 8],     [2, 4, 6],   ];   for (let i = 0; i < lines.length; i++) {     const [a, b, c] = lines[i];     if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {       return squares[a];     }   }   return null; } class Board extends React.Component {   renderSquare(i) {     return (       <Square         value={this.props.squares[i]}         onClick={() => this.props.onClick(i)}       />     );   }   render() {     return (       <div>         <div className