작성한 코드는 Tooling을 통해 각각 하나의 파일로 통합된다.
react: 컴포넌트 생성 및 관리(코어)
react-dom: 컴포넌트 DOM에 렌더링
컴포넌트 렌더링시에 컴포넌트 인스턴스를 전달해야한다.
ReactDOM.render(컴포넌트 인스턴스, DOM요소)
// 컴포넌트 클래스 const App = () => { return <div>Hi!</div> } // 컴포넌트 인스턴스 <App></App>
JSX문법을 사용하는 파일에는 항상 React를 import해야 한다.
JSX가React.createElement
로 변환된다.
이벤트 핸들링 함수 작명
onInputChange // on + 요소이름 + 이벤트 타입 handleInputChange // handle + 요소이름 + 이벤트 타입
입력에 관하여
form
태그를 사용한다.
여러 다른 이벤트 핸들러(ex,enter
클릭, 버튼 클릭 등)를 등록할 필요 없이 단 하나의 이벤트 핸들러(onSubmit)로 처리 가능하다.
타이핑시 이벤트 트리거를 통해 인풋값은 바뀌지 않고 state를 통해 업데이트 한다.
<input value={state} onChange={()=>setState()} />
npm i youtube-api-search
import _ from 'lodash'
import YTSearch from 'youtube-api-search'
const videoSearch = _.debounce((term) => YTSearch({key: API_KEY, term},callback), 300)
구조가 깔끔해보임
const App = () => {
// 컴포넌트 배열 생성하여 변수에 저장
const items = arr.map(ele=><Item item={ele} />)
// 변수로 렌더링
return <ul>{items}</ul>
}
맨 위에 로딩을 리턴하여 나머지 프로세스 실행 방지
const Item = ({item}) => {
if(!item) return <div>Loading...</div>
//로직
return ...
}
로딩은 높은 상위 부모 레벨 컴포넌트에 하나만 띄운다.
(각 요소마다 넣을 경우 유저는 여러개의 스피너를 보게 된다.)
어플리케이션 state 관리 => 평범한 자바스크립트 Object
(컴포넌트 state와 다름)
하나의 리듀서는 하나의 state값 생성
combineReducers
로 state매핑const rootReducer = combineReducers({ books: bookReducer activeBook: activeBookReducer })
리액트 디렉토리 구조
components: 뷰를 담당하는 컴포넌트
container: 리덕스에 의해 관리되는 스테이트에 직접 접근하는 컴포넌트(데이터 컴포넌트)
리액트와 리덕스를 연결하는 역할
데이터 컴포넌트에 스테이트 주입 => container
클래스 컴포넌트
import { connect } from 'react-redux'
class BookList extends Component {}
// 컴포넌트에게 전달될 props 객체
function mapStateToProps(state, ownProps?) {
return { books: state.books }
};
// 컴포넌트에게 전달될 props 객체
function mapDispatchToProps(dispatch, ownProps?) {
return bindActionCreators({ selectBook, }, dispatch)
};
export default connect(mapStateToProps,mapDispatchToProps)(BookList)
리덕스는 리듀서가 undefined를 반환하는 것을 금지한다.
// state 기본값 null로 설정 export default function(state=null,action){ }
리덕스 미들웨어: 액션을 인자로 받아 로직을 처리한 뒤 다시 액션을 반환하는 함수
액션 payload가 promise인 경우 액션을 멈춘 후, 요청이 끝나면 받은 값을 payload에 담아 전달한다.
미들웨어 설정
const store = createStore(reducer,applyMiddleware(ReduxPromise));
액션 생성 함수
export function fetchData(){
const res = axios.get(url)
return {
type: FETCH_DATA,
payload: res // 비동기 처리 없이 promise 전달
}
}
리듀서
export default function(state = [], action) {
switch (action.type) {
case FETCH_DATA:
// action.payload는 프로미스가 아닌 응답값
return [action.payload.data, ...state];
}
return state;
}
npm i react-sparklines@1.6.0
// 차트 값 배열을 map함수를 사용하여 생성한다.
const data = cityData.list.map(weather => weather.main.temp);
<Sparklines height={120} width={180} data={data}>
<SparklinesLine color={props.color} />
<SparklinesReferenceLine type="avg" />
</Sparklines>
차트 평균값 구하기
lodash
사용function average(data) { return _.round(_.sum(data) / data.length); }
History: url이 변경되는 것을 관찰하고 업데이트
React-Router: 새 URL에 맞는 새로운 컴포넌트를 리액트에 전달