동적으로 리스트 안의 값을 추가하여 보여줘야 하는 경우가 있다. ReactJS 에서는 render() 안의 값을 동적으로 보여주기 위해서는 state 를 이용해야 한다.
import React from 'react';
import TmpComponent from './TmpComponent');
export default class TestClass extends React.Component {
constructor(props) {
super(props);
this.state = {
resultAjax: [],
tmpState: [],
checked: []
}
}
componentDidMount() {
// Ajax 호출
...
for (..) {
checked[i] = false;
this.setState({resultAjax: response.resultData, checked: checked});
}
...
};
render() {
let {tmpState} = this.state;
this.state.resultAjax.map((data, i)) => {
tmpState[i] = (
<TmpComponent
key={`tmp${i}`}
checked={checked[i]}
/>
)
}
return (
{tmpState}
)
}
}
위와 같이 render() 함수 안에서 한번만 만들 때는 문제없이 동적으로 리스트가 추가된 것을 확인할 수 있을 것이다. 다만, 이 때의 동적이란 의미는 componentDidMount() 함수에서 Ajax 호출 결과로 반환된 데이터의 리스트에만 국한된다.
하지만, 저렇게 만들고 나서 어떤 버튼 이벤트를 통해 또 추가하고 싶을 경우에는 어떻게 될까?
물론, 위와 비슷하게 만들면 될 것이다. 아래를 참고하자.
addComponent = () => {
let {checked, tmpState} = this.state;
let tmpCount = tmpState.length;
checked[tmpCount] = false;
tmpState[tmpCount] = (
<TmpComponent
key={`tmp${i}`}
checked={checked[tmpCount]}
/>
);
};
위와 같이 어떠한 이벤트에 addComponent() 함수를 호출하면 아마 화면 상에는 TmpComponent가 잘 추가되어 나올 것이다.
하지만, 내가 TmpComponent 컴포넌트의 checked 속성에 CSS를 변경해 주는 등의 이벤트를 만들어 놨을 경우에 문제가 생긴다.
render() 함수 내에서 동적으로 추가된 컴포넌트들은 CSS 변경이 잘 적용되지만 addComponent() 함수에서 새로 추가된 컴포넌트들은 CSS 변경이 안될 것이다.
addComponent() 함수와 같이 처리하고 싶은 경우가 있다면 아래의 코드처럼 수정을 하면 잘 될 것이다.
import React from 'react';
import TmpComponent from './TmpComponent');
export default class TestClass extends React.Component {
constructor(props) {
super(props);
this.state = {
resultAjax: [],
tmpState: [],
checked: []
}
}
componentDidMount() {
// Ajax 호출
...
for (..) {
checked[i] = false;
this.setState({resultAjax: response.resultData, checked: checked});
}
...
};
addComponent = () => {
let {checked, tmpState} = this.state;
let tmpCount = tmpState.length;
checked[tmpCount] = false;
tmpState[tmpCount] = (
<TmpComponent
key={`tmp${i}`}
checked={checked[tmpCount]}
/>
);
};
cloneTmpState = (child, index) => {
const {checked} = this.state;
return React.cloneElement(child, {
checked: checked[index],
...
// 새로 추가하고 싶은 속성들
});
};
render() {
let {tmpState} = this.state;
this.state.resultAjax.map((data, i)) => {
tmpState[i] = (
<TmpComponent
key={`tmp${i}`}
checked={checked[i]}
/>
)
}
return (
{tmpState}
{React.Children.map(tmpState, (child, index) => {
return this.cloneTmpState(child, index)
})}
)
}
}
한 번 컴포넌트로 생성된 속성은 state 값이 바뀌어도 인식을 하지 못한다. 따라서, cloneElement() 를 이용하여 render() 가 다시 그려질 때, 속성값을 새로 추가해주면 된다.
'JavaScript > React' 카테고리의 다른 글
[ReactJS] scroll to top (0) | 2017.07.31 |
---|---|
[React] 속도 향상 (0) | 2017.07.25 |
[ECMAScript6] get max number in list (0) | 2016.12.28 |
[React] window.print (0) | 2016.11.30 |
[React] jspdf, jspdf-autotable (1) | 2016.11.29 |
댓글