.png)
input에 변화가 있으면 onInputChange가 호출되는데 이때 onInputChange 내부의 this.setState()는 undefined이다.onChange의 이벤트리스너로 onInputChange를 할당함으로써 새로운 함수가 생겨났고, 그 함수가 호출되는 것이기 때문this를 자동으로 바인딩해준다.)onChange={(event) => onInputChange(event)}render() 내부에서 바인딩을 하게 되면 렌더링마다 새로운 함수가 생겨나서 성능을 떨어뜨릴 수 있다.// components/search_bar.js
export default class SearchBar extends Component {
constructor(props) {
...
}
onInputChange(event) {
this.setState({ term: event.target.value });
}
render() {
return (
<form className="input-group">
<input
...
value={this.state.term}
onChange={this.onInputChange}
/>
...
</form>
);
}
}
constructor에서 컴포넌트와 컨텍스트 바인딩을 해준다.constructor(props) {
super(props);
this.state = { term: '' };
// onInputChange함수에 SearchBar 컴포넌트를 바인딩하여 덮어씌운다.
this.onInputChange = this.onInputChange.bind(this);
}
👉 이벤트 핸들러를 레퍼런스로 전달하고, 컴포넌트와 생성자에서 바인딩함으로써 최적화한 코드 완성!
액션 생성자에서 리듀서 사이에서 액션을 가로채어 액션을 막거나 수정하는 등 일종의 문지기 역할을 한다.
npm install --save redux-promise: redux-promise 설치 (Ajax 요청 처리를 위해서)...
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
// redux-promise 가져오기
import ReduxPromise from 'redux-promise';
import App from './components/app';
import reducers from './reducers';
// applyMiddleware의 첫 번째 인자로 ReduxPromise 보내기
const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
ReactDOM.render(
...
);
npm install --save axios: axios 설치axios.get(url): url에 대한 ajax 리퀘스트// actions/index.js
import axios from 'axios';
...
// 리듀서에서 오타로 인한 문제를 막기 위해 변수를 선언
export const FETCH_WEATHER = 'FETCH_WEATHER';
export function fetchWeather(city) {
const url = `${ROOT_URL}&q=${city},us`;
const request = axios.get(url);
return {
type: FETCH_WEATHER,
payload: request,
};
}
미들웨어와 액션 흐름
1. 액션 생성자가 액션 리턴
2. 미들웨어로 들어감
3. 액션이 payload 값으로 promise를 가지고 있는지 판단
👉 굳이 비동기 데이터를 다루는 코드를 작성하지 않았지만 미들웨어를 통해 비동기 요청과 promise를 관리하여 깔끔한 코드 유지
state를 직접 변경하면 안 되기 때문에 push() 대신 concat()을 호출하여 새로운 배열을 만든다.// reducers/reducer_weather.js
import { FETCH_WEATHER } from '../actions/index';
export default function (state = [], action) {
switch (action.type) {
case FETCH_WEATHER:
return [action.payload.data, ...state];
}
return state;
}
return state.concat([action.payload.data]);ES6 문법을 사용하여 아래와 같이 작성할 수 있다.
return [action.payload.data, ...state];새로운 배열을 만드는데, 첫 번째 요소는
action.payload.data이고 다음 요소는state의 모든 요소를 가져와서 넣어준다.
npm install --save react-sparklines: react-sparklines 설치import하고 문서 참고해서 차트 작성 가능// components/chart.js
import React from 'react';
import { Sparklines, SparklinesLine } from 'react-sparklines';
export default (props) => {
return (
<div>
<Sparklines height={120} width={180} data={props.data}>
<SparklinesLine color={props.color} />
</Sparklines>
</div>
);
};
// containers/weather_list.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Chart from '../components/chart';
class WeatherList extends Component {
renderWeather(cityData) {
const name = cityData.city.name;
const temps = cityData.list.map((weather) => weather.main.temp);
return (
<tr key={name}>
<td>{name}</td>
<td>
<Chart data={temps} color="orange" />
</td>
</tr>
);
}
render() {
...
}
}
...
const lon = cityData.city.coord.lon; const lat = cityData.city.coord.lat;위의 코드와 아래 코드는 동일하다.
const { lon, lat } = cityData.city.coord;
JSX DOM에 스타일 지정
<div style={{ height: '100%' }} />
- 바깥 괄호(
{})는 자바스크립트 문법- 안쪽 괄호(
{})는 자바스크립트 오브젝트
여긴 어디... 나는 누구...