2017-04-25 18 views
1

我有一個與我的REDX應用程序的問題:它正確地分派相關的動作和更新狀態,但由於某種原因,UI不會更新。 99%的問題似乎是由於國家實際上發生了變異而引起的,但我確信事實並非如此。以下是相關文件:React/Redux:儘管調度和狀態更改正確,但組件不會重繪。 (不涉及突變)

容器組件:

import React from 'react'; 
 
import { bindActionCreators } from 'redux'; 
 
import { connect } from 'react-redux'; 
 
import PropTypes from 'prop-types'; 
 
import requestEvents from 'actions/feedActions'; 
 
import { FeedElement, feedElementTypes } from '../components/feed/feedElement'; 
 

 
class Feed extends React.Component { 
 
    componentWillMount() { 
 
    this.props.requestEvents(); 
 
    } 
 
    render() { 
 
    console.log('Rendering feed'); 
 
    const listOfFeedElements = this.props.listOfFeedElements; 
 
    let elementsToDisplay; 
 
    if (listOfFeedElements.length === 0) { 
 
     elementsToDisplay = <li><p> No elements to display</p></li>; 
 
    } else { 
 
     const numOfElementsToDisplay = listOfFeedElements.length <= 10 ? 
 
     listOfFeedElements.length : 10; 
 

 
     const sortedElementsToDisplay = listOfFeedElements.concat().sort(
 
     (e1, e2) => e1.timestamp - e2.timeStamp); 
 

 
     elementsToDisplay = 
 
     sortedElementsToDisplay 
 
     .slice(0, numOfElementsToDisplay) 
 
     .map(el => FeedElement(el)); 
 
    } 
 

 
    return (
 
     <div className="socialFeedContainer"> 
 
     <h1> Social feed </h1> 
 
     <ol> 
 
      {elementsToDisplay} 
 
     </ol> 
 
     </div> 
 

 
    ); 
 
    } 
 
} 
 

 
Feed.propTypes = { 
 
    requestEvents: PropTypes.func.isRequired, 
 
    listOfFeedElements: PropTypes.arrayOf(PropTypes.shape({ 
 
    timeStamp: PropTypes.number.isRequired, 
 
    type: PropTypes.oneOf(Object.keys(feedElementTypes)).isRequired, 
 
    targetDeck: PropTypes.string.isRequired, 
 
    concernedUser: PropTypes.string.isRequired, 
 
    viewed: PropTypes.bool.isRequired })), 
 
}; 
 

 
Feed.defaultProps = { 
 
    listOfFeedElements: [], 
 
}; 
 

 

 
function mapDispatchToProps(dispatch) { 
 
    return bindActionCreators({ requestEvents }, dispatch); 
 
} 
 

 
function mapStateToProps(state) { 
 
    const { feedState } = state.local.feed.listOfFeedElements; 
 
    return { 
 
    feedState, 
 
    }; 
 
} 
 

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

減速:

import Immutable from 'seamless-immutable'; 
 
import { types } from 'actions/feedActions'; 
 

 
const initialState = Immutable({ 
 
    listOfFeedElements: [], 
 
    sentRequestForList: false, 
 
    receivedList: false, 
 
}); 
 

 
function feedReducer(state = initialState, action) { 
 
    switch (action.type) { 
 
    case types.REQUEST_FEED_ELEMENTS: 
 
     return Immutable.merge(state, { 
 
     sentRequestForList: true, 
 
     receivedList: false, 
 
     }); 
 
    case types.RECEIVED_LIST: 
 
     return Immutable.merge(state, { 
 
     sentRequestForList: false, 
 
     receivedList: true, 
 
     listOfFeedElements: action.payload.listOfNotifications, 
 
     }); 
 
    default: 
 
     return state; 
 
    } 
 
} 
 

 
export default feedReducer;

城:

import { takeLatest, put } from 'redux-saga/effects'; 
 

 
import { types } from 'actions/feedActions'; 
 
import feedApiCall from './feedApiCall'; 
 

 
export function* getFeedFlow() { 
 
    try { 
 
    console.log('sent request for feed'); 
 

 
    const listOfNotifications = feedApiCall(); 
 

 
    yield put({ 
 
     type: types.RECEIVED_LIST, 
 
     payload: { 
 
     listOfNotifications, 
 
     }, 
 
    }); 
 
    } catch (error) { 
 
    yield put({ 
 
     type: types.RECEPTION_ERROR, 
 
     payload: { 
 
     message: error.message, 
 
     statusCode: error.statusCode, 
 
     }, 
 
    }); 
 
    } 
 
} 
 

 
function* feedUpdateWatcher() { 
 
    yield takeLatest(types.REQUEST_FEED_ELEMENTS, getFeedFlow); 
 
} 
 

 
export default feedUpdateWatcher;

該操作得到調度和狀態修改(最後我有一個列表與組件)。然而,該組件只呈現一次,因爲我可以從調用console.log中檢查。

+1

對於redux,我仍然生疏,但在您的mapStateToProps中,當組件呈現屬性listOfFeedElements時,您好像綁定了一個屬性'feedState'。 – Gimby

+0

哪些操作被稱爲REQUEST_FEED_ELEMENTS或RECEIVED_LIST? –

+0

@Gimby:很好,但這不是問題。 'console.log('Rendering feed');'只打印一次,這意味着渲染函數甚至不會被第二次調用。 – Gloomy

回答

1

根組件看起來相當可疑。

首先,從命名代碼和協議開始,FeedElement類看起來像React,但它在地圖中用作簡單函數。不管有沒有類似的外觀鑑於東西:

elementsToDisplay = 
     sortedElementsToDisplay 
     .slice(0, numOfElementsToDisplay) 
     .map(el => (<FeedElement {...el} />)); 

其次,返回對象const {feedState} = state.local.feed.listOfFeedElements;進一步您解決this.props.listOfFeedElements - 原則上這樣的領域並不存在。並從state.local.feed的一部分承擔?

另外,您使用的是redux和saga,所以最好將其構成一個純粹的功能部件,並去掉componentWillMount的調用,而這個調用與期望的架構並不真正對應。

+0

謝謝,確實命名是導致問題的原因。 然而,我不明白你的最後一部分,你是什麼意思的「時間你使用的REDX和傳奇」?你如何建議我在頁面加載時啓動API調用(saga)? – Gloomy

+0

@Gloomy是的,啓動傳奇的一般用例是運行傳奇中間件與創建存儲庫,即https://github.com/redux-saga/redux-saga#mainjs 通常你的傳奇應該是獨立的反應componrent每SE –

相關問題