Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React Redux:连接的子组件未接收道具_Javascript_Reactjs_Redux_React Redux - Fatal编程技术网

Javascript React Redux:连接的子组件未接收道具

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未

我似乎不明白问题出在哪里。我有一个名为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一样

组件如下所示。我试着尽可能地简化它们

显示项目

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是一个相当昂贵的操作。