gpt4 book ai didi

javascript - 状态更新但不重新渲染

转载 作者:行者123 更新时间:2023-11-30 11:18:08 24 4
gpt4 key购买 nike

我刚开始学习 React Native + Redux。看来我成功更新了状态,但 View 没有改变(没有重新渲染)。谁能给我一个解决这个问题的建议......?

我尝试使用 console.log 进行调试并点击屏幕。

“selectedMenuMap”:对象{“item2”:是的,“项目 3”:假的,"},这只是日志的一部分,我可以看到状态实际上已经改变了......

Reducer.js

import { SELECT_MENU } from './actions.js';

const initialState = {
menu:
[
{key: 'item1', title: 'AAA',
detail: [
{key: 'detail_item1', title: 'AA', price: '1000', time: '30'},
{key: 'detail_item2', title: 'AB', price: '1100', time: '35'},
{key: 'detail_item3', title: 'AC', price: '1200', time: '40'},
]},
{key: 'item2', title: 'BBB',
detail: [
{key: 'detail_item1', title: 'BA', price: '1000', time: '30'},
{key: 'detail_item2', title: 'BB', price: '1100', time: '35'},
{key: 'detail_item3', title: 'BC', price: '1200', time: '40'},
]},
{key: 'item3', title: 'CCC',
detail: [
{key: 'detail_item1', title: 'CA', price: '1000', time: '30'},
{key: 'detail_item2', title: 'CB', price: '1100', time: '35'},
{key: 'detail_item3', title: 'CC', price: '1200', time: '40'},
]},
],
selectedMenuMap: {}
};

function menuList(state = initialState, action) {
switch (action.type) {
case SELECT_MENU:
console.log('state');
let newState = Object.assign({}, state);
newState.selectedMenuMap[action.key] = !state.selectedMenuMap[action.key];
console.log(newState === state);
return newState;
default:
return state;
}
}

export default menuList;

容器.js

import MenuList from '../components/MenuList.js';
import { selectMenu } from '../actions.js';
import { connect } from 'react-redux';

const mapStateToProps = state => ({
menu: state.menu,
selectedMenuMap: state.selectedMenuMap,
});

const mapDispatchToProps = dispatch => {
return {
onPressMenu: key => {
dispatch(selectMenu(key))
},
}
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(MenuList);

组件.js

import React, { Component, Purecomponent } from 'react';
import {
FlatList,
} from 'react-native';
import MenuItem from './MenuItem.js';

export default class MenuList extends React.PureComponent {
_renderItem = ({item}) => (
<MenuItem
id={item.key}
onPressItem={() => this.props.onPressMenu(item.key)}
selected={this.props.selectedMenuMap[item.key]}
title={item.title}
detail={item.detail}
/>
);

render() {console.log(this.props);
return (
<FlatList
data={this.props.menu}
renderItem={this._renderItem}
/>
);
}
}

这是个问题吗???state 和 newState 是一样的吗??

function menuList(state = initialState, action) {
switch (action.type) {
case SELECT_MENU:
console.log('reducer');
let newState = Object.assign({}, state);
newState.selectedMenuMap[action.key] = !state.selectedMenuMap[action.key];
console.log('oldState');
console.log(state.selectedMenuMap);
console.log('newState');
console.log(newState.selectedMenuMap);
console.log(newState.selectedMenuMap === state.selectedMenuMap);
return newState;
default:
return state;
}
}

17:35:33: reducer
17:35:33: oldState
17:35:33: Object {
17:35:33: "item3": true,
17:35:33: }
17:35:33: newState
17:35:33: Object {
17:35:33: "item3": true,
17:35:33: }
17:35:33: true

最佳答案

Object.assign() 仅执行浅拷贝。所以这个语句并没有像你期望的那样工作。

  let newState = Object.assign({}, state);

虽然 newStatestate 是不同的对象,但嵌套的 newState.selectedMenuMap 指向与 state.selectedMenuMap< 相同的对象。你不能在不改变两者的情况下改变一个。

相反,请确保您不修改原始状态。这样的事情应该有效。

const newState = { ...state,
selectedMenuMap: { ...state.selectedMenuMap,
[action.key]: !state.selectedMenuMap[action.key]
}
}

每个展开操作 {...foo}Object.assign({}, foo) 的作用相同,因此我们创建了两个 的浅拷贝>state 然后是 state.selectedMenuMap。现在 state.selectedMenuMapnewState.selectedMenuMap 指向不同的对象,redux 会知道应该重新渲染连接到这部分状态树的组件。

这看起来有点复杂,原始状态是否发生变异可能不是很明显。

在更新嵌套状态切片时避免改变现有状态的一种方法是使用诸如 Ramda.js 之类的库,它从不改变作为参数传入的对象。

const newState = R.over(R.lensPath(['selectedMenuMap', action.key]), R.not, state)

关于javascript - <Redux> 状态更新但不重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50781765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com