如何创建独立于数组更新的组件列表
How to create a list of components which update independed out of an array
我在一个数组中有一个对象列表,我将其作为初始状态加载到减速器中。
当我研究该数组中的一个对象(将级别增加 1)时,整个渲染列表都会更新,即使其余部分保持不变。
有没有办法只更新 Redux 中该列表中的一个组件?
减速机
const researchObj = fromJS{
researchList: [{
id: 1,
name: 'iron',
level: 0
}, {
id: 2,
name: 'defence',
level: 0
}]
})
export default function (state = researchObj, action) {
switch (action.type) {
case 'RESEARCH':
return research(state, action.researchId);
}
return state;
}
function research(state, researchId) {
const researchObjIndex = state.get('researchList').findIndex(
(research) => research.get('id') === researchId
);
let researchedItem = state.get('researchList').get(researchObjIndex);
researchedItem = researchedItem.update('level', level => level + 1);
let newState = state.update('researchList', researchList => researchList.set(researchObjIndex, researchedItem));
return newState;
}
ResearchList 容器
export class ResearchList extends React.Component {
render() {
this.getResearchCost = (baseCost, costIncrease, level) => {
return baseCost + (baseCost * costIncrease * level);
}
return <section className={styles.root}>
{this.props.researchList.map(item =>
<ResearchItem
key={item.get('id') }
id={item.get('id') }
name={item.get('name') }
level={item.get('level') }
baseProduction={item.get('baseProduction') }
productionIncrease={item.get('productionIncrease') }
upgradeCost={this.getResearchCost(item.get('baseCost'), item.get('costIncrease'), item.get('level')) }
doResearch={this.props.research}
/>
) }
</section>
}
}
ResearchList.propTypes = {
researchList: React.PropTypes.object.isRequired,
research: React.PropTypes.func.isRequired
}
function mapStateToProps(state) {
return {
researchList: state.game.get('researchList')
};
}
export const ResearchListContainer = connect(mapStateToProps, actions)(ResearchList);
ResearchItem 组件
export default class ResearchItem extends React.Component {
render() {
return <div className={styles.root}>
<div className={styles.stats_container}>
<span className={styles.stats_item}>Current Level: {this.props.level}</span>
<span className={styles.stats_item}>Current Production: {(this.props.level * this.props.productionIncrease) + this.props.baseProduction}</span>
</div>
<div className={styles.research_btn_container}>
<button className={styles.research_btn} onClick={() => this.props.doResearch(this.props.id) } >{this.props.name} ({this.props.upgradeCost}) </button>
</div>
</div>
}
}
根据商店更改有选择地更新组件的唯一方法是将 mapStateToProps
设置为商店的适当部分。在您的情况下,您有一个容器需要访问的数组,因此您不能进一步限制商店更新。相反,我建议将 shouldComponentUpdate
添加到 ResearchItem
组件。在那里,您可以检查 newProps
与 this.props
并进行相等性检查。如果 属性 你关心的变化,让它更新,否则不要。
shouldComponentUpdate
规格:
需要 nextProps, nextState
。它需要一个 return 布尔值,所以你可以说,
return nextProps.level !== this.props.level;
这意味着它只会在级别不同时更新。使用您认为合适的任何条件。
我在一个数组中有一个对象列表,我将其作为初始状态加载到减速器中。 当我研究该数组中的一个对象(将级别增加 1)时,整个渲染列表都会更新,即使其余部分保持不变。 有没有办法只更新 Redux 中该列表中的一个组件?
减速机
const researchObj = fromJS{
researchList: [{
id: 1,
name: 'iron',
level: 0
}, {
id: 2,
name: 'defence',
level: 0
}]
})
export default function (state = researchObj, action) {
switch (action.type) {
case 'RESEARCH':
return research(state, action.researchId);
}
return state;
}
function research(state, researchId) {
const researchObjIndex = state.get('researchList').findIndex(
(research) => research.get('id') === researchId
);
let researchedItem = state.get('researchList').get(researchObjIndex);
researchedItem = researchedItem.update('level', level => level + 1);
let newState = state.update('researchList', researchList => researchList.set(researchObjIndex, researchedItem));
return newState;
}
ResearchList 容器
export class ResearchList extends React.Component {
render() {
this.getResearchCost = (baseCost, costIncrease, level) => {
return baseCost + (baseCost * costIncrease * level);
}
return <section className={styles.root}>
{this.props.researchList.map(item =>
<ResearchItem
key={item.get('id') }
id={item.get('id') }
name={item.get('name') }
level={item.get('level') }
baseProduction={item.get('baseProduction') }
productionIncrease={item.get('productionIncrease') }
upgradeCost={this.getResearchCost(item.get('baseCost'), item.get('costIncrease'), item.get('level')) }
doResearch={this.props.research}
/>
) }
</section>
}
}
ResearchList.propTypes = {
researchList: React.PropTypes.object.isRequired,
research: React.PropTypes.func.isRequired
}
function mapStateToProps(state) {
return {
researchList: state.game.get('researchList')
};
}
export const ResearchListContainer = connect(mapStateToProps, actions)(ResearchList);
ResearchItem 组件
export default class ResearchItem extends React.Component {
render() {
return <div className={styles.root}>
<div className={styles.stats_container}>
<span className={styles.stats_item}>Current Level: {this.props.level}</span>
<span className={styles.stats_item}>Current Production: {(this.props.level * this.props.productionIncrease) + this.props.baseProduction}</span>
</div>
<div className={styles.research_btn_container}>
<button className={styles.research_btn} onClick={() => this.props.doResearch(this.props.id) } >{this.props.name} ({this.props.upgradeCost}) </button>
</div>
</div>
}
}
根据商店更改有选择地更新组件的唯一方法是将 mapStateToProps
设置为商店的适当部分。在您的情况下,您有一个容器需要访问的数组,因此您不能进一步限制商店更新。相反,我建议将 shouldComponentUpdate
添加到 ResearchItem
组件。在那里,您可以检查 newProps
与 this.props
并进行相等性检查。如果 属性 你关心的变化,让它更新,否则不要。
shouldComponentUpdate
规格:
需要 nextProps, nextState
。它需要一个 return 布尔值,所以你可以说,
return nextProps.level !== this.props.level;
这意味着它只会在级别不同时更新。使用您认为合适的任何条件。