我正在使用列表应用程序,但是组件无法正确更新时遇到问题。我从JSON文件中提取用户列表,并将其保存为状态。我正在使用上下文将状态和其他信息传递给我的不同组件。最小的组成部分是用户项目,分为可编辑的列表。这是我遇到问题的项目列表。
例如,我有两个不同的JSON文件:
[{"userId": 81944,
"listId": 1,
"title": "testa",
"items": [
{
"listItemId": 0,
"product": "walnuts",
"quantity": 1,
"category": "Bakery",
"unit": "Each",
"cart": false
},
{
"listItemId": 1,
"product": "syrup",
"quantity": 1,
"category": "Beverages",
"unit": "Each",
"cart": true
},
{
"listItemId": 2,
"product": "cinnamon",
"quantity": 6,
"category": "Bakery",
"unit": "Each",
"cart": false
},
{
"listItemId": 3,
"product": "gabonzo beans",
"quantity": 1,
"category": "Canned Goods",
"unit": "Each",
"cart": true
},
{
"listItemId": 4,
"product": "diced tomatos",
"quantity": 7,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 5,
"product": "milk",
"quantity": 1,
"category": "Dairy",
"unit": "Oz",
"cart": false
},
{
"listItemId": 6,
"product": "salmon",
"quantity": 3,
"category": "Meat",
"unit": "Lb",
"cart": false
}]},{
"userId": 78863,
"listId": 4,
"title": "testd",
"items": [
{
"listItemId": 0,
"product": "half and half",
"quantity": 1,
"category": "Dairy",
"unit": "Each",
"cart": false
},
{
"listItemId": 1,
"product": "Blue Cheese",
"quantity": 1,
"category": "Dairy",
"unit": "Each",
"cart": false
},
{
"listItemId": 2,
"product": "Garlic",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 3,
"product": "Chestnuts",
"quantity": 1,
"category": "Other",
"unit": "Each",
"cart": false
},
{
"listItemId": 4,
"product": "Balsamic Vinegar",
"quantity": 1,
"category": "Other",
"unit": "Each",
"cart": false
},
{
"listItemId": 5,
"product": "Onions",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
},
{
"listItemId": 6,
"product": "Flax Seed",
"quantity": 1,
"category": "others",
"unit": "Each",
"cart": false
},
{
"listItemId": 7,
"product": "Plantains",
"quantity": 1,
"category": "Produce",
"unit": "Each",
"cart": false
}]}]
在我的应用程序中,我有一个对话框,允许我在列表之间切换。然后,我获取列表并将其传递给要在屏幕上绘制的自定义组件。
import React, {useState,useEffect} from 'react';
const Card=(props)=>{
//console.log('prop');
const [cart, setCart] = useState(props.cart);
const [Product, setProduct] = useState(props.item);
const [Quantity, setQuantity] = useState(props.units);
// useEffect(()=>{
// setProduct(props.item)
// setQuantity(props.units)
// setCart(props.cart);
// },[])
console.log(props)
return (
<li key={props.value}>
<div>
<input type="checkbox" checked={cart} onChange={(e)=>{props.cartChange(e.target)}}/>
</div>
<div>
<input id={'product '+props.value} className='update'
type='text' value={Product}
onChange={(e)=>setProduct(e.target.value)}
/>
<br/>
<input id='quantityValue' className='update'
type='number' value={Quantity}
onChange={(e)=>setQuantity(e.target.value)}
/>
<span id='quantityType' className='update'>{props.unitType}</span>
</div>
<div>
<button id='save-button' type='button'
onClick={(e)=>{props.change(Product,Quantity,props.value)}}>✓ save</button>
<button id='delete-button' type='button'>✗ delete</button>
</div>
</li>
)
}
export default Card;
这是调用自定义组件的代码。您会看到我是从array.map()调用的,这些数组很好,并且其中包含正确的信息。
import React, {useContext,useEffect} from 'react';
import {DataContext} from '../../../context/test/DataContext'
import Card from './ItemCard';
const update=(x)=>{
console.log(x)
}
const List = () =>{
const {listId} = useContext(DataContext);
const {userItemList} = useContext(DataContext);
const {GetItemList} = useContext(DataContext);
const {ListSplit} = useContext(DataContext);
const {foundList} = useContext(DataContext);
const {findList} = useContext(DataContext);
const {Updater} = useContext(DataContext);
const {cartUpdater} = useContext(DataContext);
useEffect(()=>{
GetItemList();
},[listId])
useEffect(()=>{
ListSplit();
},[userItemList])
// console.log(findList);
// console.log(foundList);
return(
<div>
<p>To find:</p>
<ul>
{findList.map((item,index)=><Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartUpdater} change={Updater} />)}
</ul>
<p>Found:</p>
<ul>
{foundList.map((item,index)=><Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartUpdater} change={Updater} />)}
</ul>
</div>
)
}
export default List;
每次切换此设置时,我注销的控制台道具都会正确更改。另外,如果我查看开发工具(chrome)中的组件,我会看到状态应该是正确的,但是我在屏幕上看到的是不正确的。例如第二个项目是肉桂,如果我切换到第二个列表,则应该是蓝纹奶酪。道具随状态变化,但我在屏幕上看到的仍然是肉桂。
我知道我可能没有清楚地解释它,但是下面是我在说什么的屏幕截图。
答案 0 :(得分:0)
您已接近注释掉的代码。由于您将道具设置为状态(这是一个坏主意,我将在底部讨论),因此您的awk -v G="$g" -v theta="$theta_vs" -v z="$z_s" '{R=0; if($12 || $13) R=((G/theta)*($11-theta)*($8-z))/(($12^2)+($13^2)); print $0,R }' Input_file
仅在初始状态下设置状态。您想观看这些道具并在更新时进行更新。
useState
useEffect(() => {
setProduct(props.item)
setQuantity(props.units)
setCart(props.cart);
}, [props.item, props.units, props.cart]);
观察数组中的项目以了解是否应该触发。
作为旁注-为状态分配道具是一个坏主意,您已经知道了原因-它们不会自动更新。您应该将这些道具放置在父项上,然后将它们作为道具传递下来并直接使用。您也可以将传承者作为道具传下来,从而可以更新父项。
This article,在引用基于类的React组件时,如果您希望阅读它,可能会提供更多信息。
useEffect
const { useState } = React;
const initialItems = [
{
listItemId: 1,
product: 'syrup',
quantity: 1,
category: 'Beverages',
unit: 'Each',
cart: true,
},
{
listItemId: 2,
product: 'cinnamon',
quantity: 6,
category: 'Bakery',
unit: 'Each',
cart: false,
},
{
listItemId: 3,
product: 'garbanzo beans',
quantity: 1,
category: 'Canned Goods',
unit: 'Each',
cart: true,
},
];
const Parent = () => {
const [items, setItems] = useState(initialItems);
const updateProduct = listItemId => (e) => {
setItems(items.map((item) => {
if (item.listItemId === listItemId) {
return { ...item, product: e.target.value };
}
return item;
}));
};
const updateQuantity = listItemId => (e) => {
setItems(items.map((item) => {
if (item.listItemId === listItemId) {
return { ...item, quantity: e.target.value };
}
return item;
}));
};
return (
<div>
<div style={{ width: "50%" }}>
All Items - (this state lives inside the parent component)
</div>
<div>
{items.map(item => (
<div>
<div>
Product - {item.product}
</div>
<div>
Quantity - {item.quantity}
</div>
</div>
))}
</div>
<div style={{ width: "50%" }}>
{items.map(item => (
<Child item={item} updateQuantity={updateQuantity} updateProduct={updateProduct} />
))}
</div>
</div>
);
};
const Child = ({ item, updateQuantity, updateProduct }) => {
return (
<div>
<div>
<span>
Product -
</span>
<span>
<input value={item.product} onChange={updateProduct(item.listItemId)} />
</span>
</div>
<div>
<span>
Quantity -
</span>
<span>
<input value={item.quantity} onChange={updateQuantity(item.listItemId)} />
</span>
</div>
</div>
);
};
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
上面的一个小例子。父组件保存项目的状态,并在每个项目上进行映射以创建子组件。这个例子在边缘有些粗糙。您可以执行一些操作,例如在每个输入中添加<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
和data-id
来简化更新功能,或者使用name
来提升这种逻辑,但我认为这样做可以使您正确处理方向。