Javascript React Redux:连接的子组件未接收道具
我似乎不明白问题出在哪里。我有一个名为displaytems的组件,它从一个API获取一些数据和一个项目列表 我正在使用Redux操作和thunk中间件从API获取项目和数据。我将项目和其他数据作为对象数组保存到redux存储中,并将其命名为entriesData。实际数组位于entriesData.data中。我正在使用connect将状态和操作连接到DisplayItems的道具 接下来,我有一个名为GalleryItemContentV1的子组件。GalleryItemContentV1未连接到redux。它只是从DisplayItems接收数据,DisplayItems在项目数组中循环并将每个项目传递给GalleryItemContentV1。因此,DisplayItems再次通过this.props.entriesData.data循环,并将每个项作为名为entry的道具传递给GalleryItemContentV1 最后,我在GalleryItemContentV1中有一个子组件,名为TestCom。这就是问题所在。我还将从displayItem获得的项目传递给TestCom。因此,数据流是DisplayItems connected>GalleryItemContentV1 not connected>TestCom connected TestCom已连接到redux。它使用redux中的一些操作来更新entriesData.data中的项。当我在TestCom中更新this.props.entriesData.data时,GalleryItemContentV1会很好地接收更新的数据,但TestCom不会接收任何内容。TestCom中的项永远不会更新 我发现问题出在我将TestCom连接到redux时。如果TestCom没有连接到redux,它也会收到更新的道具,就像GalleryItemContentV1一样 组件如下所示。我试着尽可能地简化它们 显示项目Javascript React Redux:连接的子组件未接收道具,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我似乎不明白问题出在哪里。我有一个名为displaytems的组件,它从一个API获取一些数据和一个项目列表 我正在使用Redux操作和thunk中间件从API获取项目和数据。我将项目和其他数据作为对象数组保存到redux存储中,并将其命名为entriesData。实际数组位于entriesData.data中。我正在使用connect将状态和操作连接到DisplayItems的道具 接下来,我有一个名为GalleryItemContentV1的子组件。GalleryItemContentV1未
import React, {Component} from 'react';
import GalleryItemContentV1 from './GalleryItemContentV1';
import { connect } from 'react-redux';
import {getContestEntriesPageData} from '../../actions/contest';
class DisplayItems extends Component {
componentDidMount(){
this.props.getContestEntriesPageData(uri, search);
}
render(){
console.log('DisplayItems props', this.props);
return (
<div>
<div className="card-deck thumbnails" id="card-list">
{ this.props.entriesData.data instanceof Array ?
this.props.entriesData.data.map(function(object, i){
return <GalleryItemContentV1
entry={object} key={i}
arr_key={i}
/>;
}, this) : ''
}
</div>
</div>
)
}
}
const mapStateToProps = state => (
{
entriesData: state.entriesData,
}
)
const mapDispatchToProps = (dispatch) => {
return {
getContestEntriesPageData: (uri, search) => {
dispatch(getContestEntriesPageData(uri, search));
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(DisplayItems);
这里是我配置redux的地方,但我认为这与了解相关,因为GalleryItemContentV1可以很好地看到更新的数据
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import ContestReducer from '../reducers/contest';
export default function configureStore(initialState) {
return createStore(
ContestReducer,
initialState,
applyMiddleware(thunk)
);
}
总而言之
DisplayItems已连接,从store接收更新数据OK>GalleryItemContentV1未连接,接收更新OK>TestCom已连接,不接收更新,但在断开连接时接收更新
这是我的减速机,以防万一
import * as ContestActionTypes from '../actiontypes/contest';
const initialState = {
contest: null,
subscriptions: [],
user: null,
page: null
}
export default function Contest(state=initialState, action) {
console.log('redux action reducer: ', action)
switch(action.type) {
case ContestActionTypes.HANDLE_VOTE:
const newState = { ...state };
if (newState.entriesData) {
const index = newState.entriesData.data.findIndex(x => x.id === action.entry.id)
newState.entriesData.data[index].VotesCount = action.vote;
} else {
newState.entry.VotesCount = action.vote;
}
return newState
default:
return state;
}
}
我还注意到GalleryItemContentV1也发生了同样的事情。如果我连接它,那么它将停止从DisplayItems/redux存储接收更新
欢迎您的任何意见。谢谢 你正在改变你的状态。您正在该切片缩减器中创建顶级状态的浅层副本,但没有创建其中所有嵌套级别的副本。然后,您连接的组件正在提取state.entriesData,该数据未因引用而更改。因此,连接包装器组件认为状态根本没有改变,并且不会重新呈现您自己的组件 政府特别指出这是一个常见的错误 如果不可变地更新嵌套状态是一件非常痛苦的事情,我建议您研究一下。此外,我们的新版本在内部使用Immer,让您可以编写更简单的简化程序
另外,请参阅我的帖子,了解有关connect如何在内部工作的背景和详细信息。您正在改变您的状态。您正在该切片缩减器中创建顶级状态的浅层副本,但没有创建其中所有嵌套级别的副本。然后,您连接的组件正在提取state.entriesData,该数据未因引用而更改。因此,连接包装器组件认为状态根本没有改变,并且不会重新呈现您自己的组件 政府特别指出这是一个常见的错误 如果不可变地更新嵌套状态是一件非常痛苦的事情,我建议您研究一下。此外,我们的新版本在内部使用Immer,让您可以编写更简单的简化程序
另外,请参阅我的帖子,了解connect内部工作的背景和详细信息。是的,我还认为您正在改变您的状态。以下是减速器的TOGGLE_TODO案例。我希望这个代码片段能对您的代码起作用
case TOGGLE_TODO:
return Object.assign({}, state, {
todos: state.todos.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: !todo.completed
})
}
return todo
})
})
因此,在您的情况下,如果id匹配,则更新为action.vote。另外,请阅读有关深和浅对象复制的内容。是的,我还认为您正在改变您的状态。以下是减速器的TOGGLE_TODO案例。我希望这个代码片段能对您的代码起作用
case TOGGLE_TODO:
return Object.assign({}, state, {
todos: state.todos.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: !todo.completed
})
}
return todo
})
})
因此,在您的情况下,如果id匹配,则更新为action.vote。还可以阅读有关深和浅对象副本的内容。markerikson是对的,但我在这里发布了帮助我的具体答案 问题是,当我应该使用JSON.parseJSON.stringifystate时,我试图使用object.assign{},state,{}的常规方法更新对象entriesData中的数组,entriesData是对象,entriesData.data是数组。我必须阅读Mozilla的解释才能理解到底发生了什么。我以前见过JSON.parse解决方案,但我并不真正理解浅层克隆和深层克隆,而且,无论浅层克隆是什么,我不认为我犯了罪。事实证明,我是 这是我的最新减速机 非常好
case ContestActionTypes.HANDLE_VOTE:
const newState = JSON.parse(JSON.stringify(state));
if (newState.entriesData) {
const index = newState.entriesData.data.findIndex(x => x.id === action.entry.id)
newState.entriesData.data[index].VotesCount = action.vote;
} else {
newState.entry.VotesCount = action.vote;
}
return newState;
markerikson是对的,但我在这里发布了帮助我的具体答案 问题是,当我应该使用JSON.parseJSON.stringifystate时,我试图使用object.assign{},state,{}的常规方法更新对象entriesData中的数组,entriesData是对象,entriesData.data是数组。我必须阅读Mozilla的解释才能理解到底发生了什么。我以前见过JSON.parse解决方案,但我并不真正理解浅层克隆和深层克隆,而且,无论浅层克隆是什么,我不认为我犯了罪。事实证明,我是 这是我的最新减速机,工作非常完美
case ContestActionTypes.HANDLE_VOTE:
const newState = JSON.parse(JSON.stringify(state));
if (newState.entriesData) {
const index = newState.entriesData.data.findIndex(x => x.id === action.entry.id)
newState.entriesData.data[index].VotesCount = action.vote;
} else {
newState.entry.VotesCount = action.vote;
}
return newState;
谢谢你的代码片段!我的问题是,当我应该进行深度克隆时,我使用Object.assign进行了浅层克隆。我不确定您发布的代码段是否考虑到了这一点,但我认为不会。这应该是可以接受的答案,如果对象太大,parsestringify是一个相当昂贵的操作。Thnks用于代码段!我的问题是,当我应该进行深度克隆时,我使用Object.assign进行了浅层克隆。我不确定您发布的代码片段是否考虑到了这一点,但我认为不会。这应该是可以接受的答案,如果对象太大,parsestringify是一个相当昂贵的操作。