我正在React-Native的FlatList组件的项目上设置一个计数器。每当用户按下“ +”或“-”按钮时,如何更新列表项?
我目前能够更新状态值,但是列表不显示新状态。我曾尝试将extraData组件添加到FlatList,但是无论如何它似乎都没有更新。
这是数据结构
data: [
{
id: 1,
name: "Bread",
price: "400",
imageS: "../resources/pan-corteza-blanda.jpg",
quantity: 2
},
... more data
这是处理增量的功能
handleIncrement = i => {
this.setState(state => {
const formatData = state.data.map((item, j) => {
console.log("Id", i + " /// " + item.id);
if (item.id === i) {
item.quantity = item.quantity + 1;
return item;
} else {
return item;
}
});
console.log("FormatData" + formatData); //Displays the correct quantity of the item updated
return {
formatData
};
});
};
这是列表组件
<FlatList
data={this.state.data}
style={styles.list}
extraData={this.state.data}
renderItem={this.renderItem}
/>
我希望每次用户按下“ +”或“-”按钮时,用正确的数量值更新列表项的文本部分。
答案 0 :(得分:0)
this.state.data
从未在您的handleIncrement
上更改过,这就是您要传递给FlatList
的内容。这就是FlatList
不更新的原因。
handleIncrement
运行后,状态唯一改变的是:
{
formatData: [...stuff here]
}
也许您想传递this.state.formatData
或在handleIncrement
中将其重命名为data
。
此外,您的状态结构可能更适合作为映射,其中键为itemIds。这样,您每次想增加数量时都不需要映射整个列表。
例如
{
1: {
id: 1,
name: "Bread",
price: "400",
imageS: "../resources/pan-corteza-blanda.jpg",
quantity: 2
},
// more data...
}
现在,您的handleIncrement
如下所示:
handleIncrement = itemId => this.setState(prevState => ({
...prevState,
[itemId]: ++prevState[itemId].quantity
}))
答案 1 :(得分:0)
您需要更新数据状态而不是返回项目。
handleIncrement = i => {
const item = this.state.data[i];
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + 1 }),
...this.state.data.slice(i + 1)
]
});
};
您可以重构该函数并将其用于-
和+
。
// pass array index and quantity 1 for + and -1 for -
handleIncrement = (i, qty) => {
const item = this.state.data[i];
if (item && item.quantity === 0 && qty === -1) {
return;
}
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + qty, }),
...this.state.data.slice(i + 1),
],
});
};
下面是使用上述功能的演示,它在reactjs中。该功能也可以在本机反应中使用。
h1, p {
font-family: Lato;
}
.container {
display: flex;
flex-direction: row;
border-bottom-style: solid;
margin-bottom: 5px;
}
.image-container {
flex-grow: 0;
}
.info-container {
display: flex;
margin-left: 10px;
flex-direction: row;
}
.title {
margin-top: 0;
}
.titleContainer {
width: 100px;
}
.cover {
width: 30px;
}
.buttons {
flex-grow: 1;
display: flex;
margin-left: 10px;
}
.incrementButtons {
width: 20px;
height: 20px;
margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
class Item extends React.Component {
render() {
return (
<div className="container">
<div className="image-container">
<img className="cover" src={this.props.image} />
</div>
<div className="info-container">
<div className="titleContainer">
<p className="title">{this.props.title}</p>
</div>
<div className="buttons">
<p className="title">{this.props.qty}</p>
<img onClick={() => this.props.increment(this.props.index, -1)} className="incrementButtons" src="https://img.icons8.com/metro/26/000000/minus-math.png" />
<img onClick={() => this.props.increment(this.props.index, 1)} className="incrementButtons" src="https://img.icons8.com/metro/26/000000/plus-math.png" />
</div>
</div>
</div>
)
}
}
class App extends React.Component {
state = {
data: [
{
id: 1,
name: 'Avocado',
price: '400',
imageS: 'https://img.icons8.com/metro/26/000000/avocado.png',
quantity: 0,
},
{
id: 6,
name: 'Bread',
price: '300',
imageS: 'https://img.icons8.com/metro/26/000000/bread.png',
quantity: 0,
},
{
id: 2,
name: 'Milk',
price: '300',
imageS: 'https://img.icons8.com/metro/26/000000/milk-bottle.png',
quantity: 0,
},
],
};
handleIncrement = (i, qty) => {
const item = this.state.data[i];
if (item && item.quantity === 0 && qty === -1) {
return;
}
this.setState({
data: [
...this.state.data.slice(0, i),
Object.assign({}, this.state.data[i], { quantity: item.quantity + qty, }),
...this.state.data.slice(i + 1),
],
});
};
render() {
const items = this.state.data.map((item, index) => (
<Item qty={item.quantity} index={index} key={index} increment={this.handleIncrement} title={item.name} image={item.imageS} />
))
return (
<div>
{items}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>