簡體   English   中英

React Redux:連接的子組件未接收道具

[英]React Redux: Connected child component not receiving props

我似乎無法弄清楚問題是什么。 我有一個名為DisplayItems的組件,該組件從API(項目列表)中獲取一些數據。

我正在使用Redux操作和thunk中間件從API獲取項目和數據。 我將項目和其他數據作為對象數組保存到redux存儲,並將其命名為entriesData 實際的數組位於entriesData.data 我正在使用connect將狀態和動作連接到DisplayItems的道具。

接下來,我有一個名為GalleryItemContentV1的子組件。 GalleryItemContentV1未連接到GalleryItemContentV1 它只是從DisplayItems接收數據, DisplayItems遍歷項目數組並將每個項目傳遞給GalleryItemContentV1 因此,再次, DisplayItems遍歷this.props.entriesData.data並將每個項目作為名為entry的道具傳遞給GalleryItemContentV1

最后,我在GalleryItemContentV1有一個名為TestCom的子組件。 這就是問題所在。 我還將從DisplyItem獲得的項目傳遞給TestCom 因此,數據流為DisplayItems (已連接)> GalleryItemContentV1 (未連接)> TestCom (已連接)。

TestCom已連接到redux。 它使用redux中的一些操作來更新entriesData.data的項目。 當我在TestCom更新this.props.entriesData.dataTestCom GalleryItemContentV1接收更新的數據,但是TestCom卻什么也沒收到。 TestCom的項目永遠不會更新。

我發現問題是當我將TestCom連接到redux時。 如果TestCom沒有連接到redux,它也會收到更新的GalleryItemContentV1 ,就像GalleryItemContentV1一樣。

組件如下。 我試圖盡可能簡化它們。

DisplayItems

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);

GalleryItemContentV1

import React, { Component } from 'react';
import TestCom from './TestCom';

class GalleryItemContentV1 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
        <div>
        <TestCom entry={this.props.entry} />
      </div>
    );
    }
}
export default GalleryItemContentV1;

德訊通

我正在this.props.entry.VotesCount輸出this.props.entry.VotesCount (來自DisplayItems的項目)的TestCom 這就是問題所在。 出於某種原因,當我將TestCom連接到redux時,它的道具不會更新,但是當它與Redux斷開連接時,它的道具就會被更新。

import React, {Component} from 'react';
import { connect } from 'react-redux';

class TestCom extends Component {
  constructor(props) { 
    super(props);
  }

  render(){

    console.log('TestCom props', this.props);

    return (

      <div>{this.props.entry.VotesCount}</div>

    )
  }
}

const mapStateToProps = state => (
  {
    user: state.user
  }
)
export default connect(mapStateToProps)(TestCom);

這是我在配置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 (已連接,可以從存儲中接收更新的數據)> GalleryItemContentV1 (未連接,可以接收更新)> 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存儲接收更新。

任何輸入表示贊賞。 謝謝!

您正在改變狀態。 您正在該Slice Reducer中復制頂層狀態的淺層副本,但並未在其中復制所有嵌套層的副本。 然后,您連接的組件正在提取state.entriesData ,該引用未更改。 因此, connect wrapper組件認為狀態根本沒有改變,因此不會重新呈現您自己的組件。

“不可修改的更新模式”上Redux文檔頁面特別指出了這一點,這是一個常見錯誤。

如果一成不變地更新嵌套狀態太麻煩了,我建議您研究immer不變式更新庫 另外,我們新的redux-starter-kit軟件包內部使用Immer來編寫更簡單的reducer。

另外,請參閱我的文章慣用的Redux:React-Redux的歷史和實現,以獲取有關背景以及內部connect工作方式的詳細信息。

是的,我也認為您正在改變自己的狀態。 以下是reducer的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匹配,則update是使用action.vote 另請閱讀有關深層和淺層對象副本的信息。

markerikson是正確的,但是我在這里發布了對我有幫助的具體答案。

問題是我嘗試使用普通方法Object.assign({},state,{})來更新對象內部的數組(entriesData為對象,entriesData.data為數組)時,一直在使用JSON.parse(JSON.stringify(state))。 我必須閱讀Mozilla的解釋( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign )以了解發生了什么。 我之前看過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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM