我只是在玩Redux,因此对任何错误或不良做法表示歉意。
我基本上有计算机部件的列表,用户可以选择/取消选择这些部件。每个部分都是一个JS对象,其中包含ID,名称,价格和所选字段:
const initialState = {
products: [
{product_id: 0, product_name: "Hard Drive 320 GB 5400 RPM", price: 1450, selected: false},
{product_id: 1, product_name: "Solid State Drive 128 GB R/W - 420 MB/s", price: 1880, selected: false},
{product_id: 2, product_name: "Gigabyte MB A270S AM4 DDR4 3200HZ OC HDMI/VGA/DVI", price: 3560, selected: false},
{product_id: 3, product_name: "Asus MB A420M LGA 1151 3200HZ OC HDMI/VGA", price: 3660, selected: false},
{product_id: 4, product_name: "nVidia GTX 1050 Ti 4GB GDDR5 VRAM", price: 13450, selected: false},
{product_id: 5, product_name: "Intel i5 7200 kabylake CPU 3.6 GHz 4 cores 4 threads", price: 9800, selected: false},
{product_id: 6, product_name: "AMD Ryzed 5 2600G CPU 3.2 GHz 4 cores 4 threads", price: 9380, selected: false},
{product_id: 7, product_name: "8 GB Hyper-X DDR4 RAM memory 3200 MHz CL15", price: 3450, selected: false},
{product_id: 8, product_name: "450W Sharkoon PSU 80 plus black semi modular", price: 2250, selected: false},
{product_id: 9, product_name: "ATX Case w/ Acrilyc Glass panel & LED Strips", price: 1720, selected: false},
],
sum: 0
}
(这只是一种惯例,因此我不会从rest api或其他工具加载数据)
然后,我使用connect函数通过App组件订阅redux存储,并传入mapStateToProps和mapDispatchToProps函数:
function mapStateToProps(state){
return {
products: state.products,
sum: state.sum
}
}
function mapDispatchToProps(dispatch){
return {
toggle: (product_id) => dispatch(ACTIONS.toggle(product_id))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App)
然后在我的应用程序组件内部,创建一个const数组,我将所有产品映射到该数组,并生成一个div的JSX返回,其中包含内容,然后在每个div上添加一个事件linstener(onClick),该事件触发this.props.toggle调度:
const products = this.props.products.map(product => {
return (
<div className="product" key={product.product_id} onClick={ () => {this.props.toggle(product.product_id) }}>
<h2>{product.product_name}</h2>
{product.selected ? ('') : (<h3>{product.price}</h3>)}
</div>
)
})
当分派动作时,这就是在reducer中发生的事情:
switch(action.type){
case ACTION_TYPES.PRODUCT_TOGGLE:
const newState = state
newState.products[action.payload].selected = !newState.products[action.payload].selected
if(newState.products[action.payload].selected === true){
newState.sum = newState.sum + newState.products[action.payload].price
} else {
newState.sum = newState.sum - newState.products[action.payload].price
}
console.log(newState.sum)
return newState
default:
return state
}
如果我在化简版中进行控制台登录,我确实会看到更改的发生,但是容器组件的道具不会更新。
答案 0 :(得分:2)
您要突变state
对象,newState
和state
是相同的对象引用,这就是UI
不更新的原因。
您必须从化简器返回一个新对象。
在像这样对对象进行变异之前创建一个新对象
const newState = { ...state }
答案 1 :(得分:1)
当您运行newState = state时,您只是在创建一个变量,该变量引用与旧状态相同的对象,因此,当您为该对象分配新值时,您就是在对旧对象进行突变。
Redux和React-Redux使用严格的相等性检查来确定您的状态是否已更新。由于对象引用相同,因此认为状态没有改变。
const oldState = { a: 1 };
const newState = oldState;
newState.a = 2;
console.log(oldState);
console.log(newState);
console.log(oldState === newState);
请参阅有关不变性的这篇文章:https://redux.js.org/faq/immutable-data#why-is-immutability-required-by-redux