reactjs演示comopnent不重新渲染上REDX状态变化
情况 我有一个reactjs应用程序使用REDX。我有一个容器和一个演示组件。我的表示组件呈现一个包含简单文本输入字段数组的表单,并且我将一个'onChange'回调函数从容器传递给表示组件,该表单组件在输入其中一个文本字段时调度动作以更改redux状态。reactjs演示comopnent不重新渲染上REDX状态变化
问题 呈现组件成功地呈现了正确的值从Redux的状态文本字段呈现组件坐骑的时候,但是当我在字段中键入不更新。如果我将容器中传递给演示组件的道具记录在mapStateToProps
中,我可以看到onChange函数正确地分派到存储区,并且正在更新redux状态。但是当这种情况发生时,表示组件不会重新呈现,因此在文本字段中输入不会更新视图(键入什么也不做)。
formConnector
import { connect } from 'react-redux'
import Form from '../components/Form'
import { changeElementValue } from '../actions/actions'
const mapStateToProps = (state) => {
//e.g. state.elements = [{id:"email", value:"[email protected]"}]
let props = {
elements: state.elements,
}
//state and props.elements.{id}.value changes successfully when I
//type in one of the input fields, but
//the the Form component is not re-rendered
console.log(props)
return props
}
const mapDispatchToProps = (dispatch) => {
return {
onElementChange: (id, value) => {
dispatch(changeElementValue(id, value))
},
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Form)
表减速
function formReducer(state = initialState, action = null) {
switch(action.type) {
case types.CHANGE_ELEMENT_VALUE:
let newState = Object.assign({}, state)
newState.elements[action.id].value = action.value
return newState
default:
return state;
}
}
行动
import * as types from './actionTypes'
export function changeElementValue(id, value) {
return { type: types.CHANGE_ELEMENT_VALUE, id, value }
}
正如评论讨论的,这是由于状态变化。
试图改变你的减速机的代码如下:
case types.CHANGE_ELEMENT_VALUE: {
const newElements = state.elements.map(function(el, index) {
return action.id === index
? Object.assign({}, el, { value: action.value })
: el;
});
return Object.assign({}, state, { elements: newElements);
}
或更优雅:
case types.CHANGE_ELEMENT_VALUE:
return { ...state, elements: state.elements.map((el, index) => (
action.id === index ? { ...el, value: action.value } : el
)}
嗨,我标记为答案,因为它确实回答我的问题。其根本问题是返回的状态包含对旧状态的引用,所以没有做出反应没有检测到变化。这个答案帮助我确定了这一点,我非常感谢OB3 Kinnza和Assan。实际上,我弄糟了我的代码示例,我的问题仍然存在,因为我无法直接将解决方案应用到我的实际代码中。所以我在这里的一个新帖子更准确地重新构建了这个问题:http://stackoverflow.com/questions/41418623/change-value-deep-in-redux-state。再次感谢。 – xanld
您可以将组件代码和减速?你确定商店改变了吗?它看起来像你正在采取的值设置在state.textField.value,我不知道减速器更改(通过ID,以及它通过什么ID)。我敢打赌,问题出在那个地区 – Kinnza
@Kinnza谢谢你的采访。我有一种可怕的感觉,为了简化这篇文章的代码,我掩盖了这个问题。我的连接器实际上连接了一个呈现一组文本元素的“表单”组件。所以state包含一个id值对的数组。我将用代码重新编写示例来简单地粘贴到此处,但我可以运行以确保它复制问题。与此同时,可以想象我的组件不会识别状态变化,因为它是对状态内的数组中的数值的更改?应该使用不可变的? – xanld
好的,我还没有机会使用我的简化代码构建原型(如果需要,稍后会尝试),但是我已经更新了示例,以便它更真实地表示应用程序中发生的情况。现在有一组元素被渲染。再一次,对于我的预感,你认为表单组件(Form)没有被重新渲染,因为它没有检测到元素数组中某个值更新时状态的变化? – xanld