대응: 모든 항목을 재작성하지 않고 목록의 항목 하나를 업데이트합니다.
예를 들어 1000개의 아이템 리스트가 있다고 칩시다.React로 렌더링하면 다음과 같이 됩니다.
class Parent extends React.Component {
render() {
// this.state.list is a list of 1000 items
return <List list={this.state.list} />;
}
}
class List extends React.Component {
render() {
// here we're looping through this.props.list and creating 1000 new Items
var list = this.props.list.map(item => {
return <Item key={item.key} item={item} />;
});
return <div>{list}</div>;
}
}
class Item extends React.Component {
shouldComponentUpdate() {
// here I comparing old state/props with new
}
render() {
// some rendering here...
}
}
list map()이 비교적 길면 10~20ms 정도 걸리고, 인터페이스의 약간의 지연을 알 수 있습니다.
업데이트만 필요한 경우 매번 1000개의 React 개체를 재생하지 못하도록 할 수 있습니까?
관리 할 수 에 의해, 「」는 「」의 「관리 라이브러리」를 사용해 주세요.Parent
이 묘연하다this.state.list
의 => 고고고의의List
「」가 발생했을 때만 한다.Item
을 사용하다 개인 ★★★★★★★★★★★★★★★★★★★★★★★.Item
는 갱신되면 다시 갱신됩니다.
, '우리'를 사용한다고 .redux
.
코드는 다음과 같습니다.
// Parent.js
class Parent extends React.Component {
render() {
return <List />;
}
}
// List.js
class List extends React.Component {
render() {
var list = this.props.list.map(item => {
return <Item key={item.key} uniqueKey={item.key} />;
});
return <div>{list}</div>;
}
}
const mapStateToProps = (state) => ({
list: getList(state)
});
export default connect(mapStateToProps)(List);
// Item.js
class Item extends React.Component {
shouldComponentUpdate() {
}
render() {
}
}
const mapStateToProps = (state, ownProps) => ({
item: getItemByKey(ownProps.uniqueKey)
});
export default connect(mapStateToProps)(Item);
.getList
★★★★★★★★★★★★★★★★★」getItemByKey
.
은, 으 with신신 with.List
추가되었을 때 되었을 때 .item.key
안 되는 것)
편집:
처음에 제안했던 내용은 렌더링된 목록의 효율성 개선 가능성에 대해서만 다루었을 뿐 목록 변경에 따른 컴포넌트 재렌더링 제한에 대한 질문은 다루지 않았습니다.
첫 번째 질문에 대한 명확한 해답은 @shiaofan2406의 답변을 참조하십시오.
긴 목록을 보다 효율적이고 쉽게 렌더링할 수 있는 라이브러리:
데이터를 변경할 때 리액트 기본 조작은 모든 하위 구성요소를 렌더링하고 가상 돔을 생성하여 렌더링해야 하는 구성요소를 판단합니다.
따라서 리액션을 할 수 있는 컴포넌트는 1개뿐입니다.시간을 절약할 수 있습니다.
하시면 됩니다.shouldComponentsUpdate
목록 구성 요소에 있습니다.
이 함수에서 false가 반환되는 경우 react는 판단할 vital dom을 생성하지 않습니다.
는 이렇게 됩니다.[{name: 'name_1'}, {name: 'name_2'}]
class Item extends React.Component {
// you need judge if props and state have been changed, if not
// execute return false;
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.name === this.props.name) return false;
return true;
}
render() {
return (
<li>{this.props.name}</li>
)
}
}
리액션은 변경된 컴포넌트를 렌더링합니다.따라서 한 항목의 데이터만 변경하면 다른 항목이 렌더링되지 않습니다.
몇 가지 작업을 수행할 수 있습니다.
- 때 가동 상태로 "NODE_ENV").
NODE_ENV=production npm run build
또는 이와 유사합니다.ReactJS는 JS가 반응할 때 많은 안전 합니다.NODE_ENV
PropType 。이 기능을 끄면 리액트 렌더링 성능이 2배 이상 향상되고 프로덕션 구축에 필수적입니다(개발 중에는 사용하지 않지만 안전 검사를 통해 버그를 방지할 수 있습니다).이 정도면 지원해야 할 항목 수에 충분할 수 있습니다. - 요소가 스크롤 가능한 패널에 있고 일부 요소만 볼 수 있는 경우 요소의 가시적인 하위 집합을 렌더링하도록만 설정할 수 있습니다.이것은 물건의 높이가 고정되어 있을 때 가장 쉽다.기본 접근법은 다음과 같습니다.
firstRendered
/lastRendered
소품 목록 상태(처음에는 포함, 마지막에는 제외)에 따라 달라집니다.인List.render
, 필러를 공백으로 만듭니다.div
(또는tr
적절한 높이(해당하는 경우)의 경우firstRendered * itemHeight
렌더링한 아이템의 범위)[firstRendered, lastRendered)
그 후 나머지 높이를 가진 다른 주입구 div)(totalItems - lastRendered) * itemHeight
). 필러와 아이템에 고정키를 입력해 주세요.그런 다음 스크롤 가능한 div에서 onScroll을 처리하고 렌더링할 올바른 범위를 파악하면 됩니다(일반적으로 위와 아래에서 적절한 오버랩을 렌더링하고 가장자리에 가까워졌을 때 setState만 트리거하여 범위를 변경할 수 있습니다).더 엉뚱한 대안은 당신만의 스크롤바를 렌더링하고 구현하는 것이다(Facebook의 Fixed DataTable이 제 생각에 - https://facebook.github.io/fixed-data-table/)).https://react.rocks/tag/InfiniteScroll에는 이 일반적인 접근법의 많은 예가 있습니다. - 상태 관리 라이브러리를 사용하여 옆으로 로드 방식을 사용합니다.대규모 앱의 경우 이는 필수적입니다.항목' 상태를 위에서 아래로 넘기는 대신, 각 항목이 '전역' 상태(기존 플럭스처럼)에서 또는 반응 컨텍스트(현대 플럭스 구현, MobX 등)를 통해 자체 상태를 검색하도록 하십시오.이렇게 하면 항목이 변경될 때 해당 항목만 다시 렌더링하면 됩니다.
모든 렌더가 구성요소 목록에서 반복되지 않도록 하는 한 가지 방법은 렌더 함수 외부에서 수행하여 변수에 저장하는 것입니다.
class Item extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return this.props.item != nextProps.item;
}
render() {
return <li>{this.props.item}</li>;
}
}
class List extends React.Component {
constructor(props) {
super(props);
this.items = [];
this.update = this.update.bind(this);
}
componentWillMount() {
this.props.items.forEach((item, index) => { this.items[index] = <Item key={index} item={item} /> });
}
update(index) {
this.items[index] = <Item key={index} item={'item changed'} />
this.forceUpdate();
}
render() {
return <div>
<button onClick={() => { this.update(199); }}>Update</button>
<ul>{this.items}</ul>
</div>
}
}
언급URL : https://stackoverflow.com/questions/33080657/react-update-one-item-in-a-list-without-recreating-all-items
'programing' 카테고리의 다른 글
각도 및 SVG 필터 (0) | 2023.03.22 |
---|---|
특정 요소의 표시 여부 테스트 (0) | 2023.03.22 |
현재 JSON 개체(예: {"name":"value"})를 '시스템' 유형으로 역직렬화할 수 없습니다.컬렉션포괄적인.리스트 1 (0) | 2023.03.22 |
WebStorm 2018.1.4 + ESLint: TypeError: 이것.CliEngine은 생성자가 아닙니다. (0) | 2023.03.22 |
Fetch API에서 권한 부여 헤더 설정 (0) | 2023.03.22 |