Reputation: 329
I am having trouble figuring out why my component renders both the previous prop and the new prop instead of only the diff.
For example it renders:
[[1, 2, 3, 4, 5]]
[[6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5]]
[[6, 7, 8, 9, 10]]
[[16, 57, 8, 19, 5]]
Instead of just:
[[1, 2, 3, 4, 5]]
[[6, 7, 8, 9, 10]]
[[16, 57, 8, 19, 5]]
My main component:
class AsyncApp extends Component {
constructor(props) {
super(props)
}
lookForUpdate() {
// this function hits a endpoint every 10 sec.
setInterval(() => {
this.props.dispatch(fetchDataForReals())
}, 10000)
}
componentDidMount() {
this.props.dispatch(fetchDataForReals())
this.lookForUpdate()
}
render() {
const { graphData } = this.props;
return (
<div>
<div>hello</div>
<DataGraph graphData={graphData} />
</div>
)
}
}
function mapStateToProps(state) {
let graphData = state.payment.graphDatas
return {
graphData
}
}
export default connect(mapStateToProps)(AsyncApp)
My other component:
import React, { Component } from 'react'
export default class DataGraph extends Component {
constructor(props) {
super(props)
}
shouldComponentUpdate(nextProps) {
return nextProps.graphData !== this.props.graphData
}
render() {
return (
<div>{this.props.graphData.map(function(datas){
return datas.map(function(data, index){
return <li key={index}>{data.series}</li>
})
})}</div>
)
}
}
export default DataGraph;
My action.js
function requestDataArray() {
return {
type: REQUEST_DATA
}
}
function recieveDataArray(data) {
return {
type: RECIEVE_DATA,
data: data.map(child => child),
receivedAt: Date.now()
}
}
function fetchData() {
return dispatch => {
dispatch(requestDataArray())
return fetch('//localhost:3000/api/v1/data', {
mode: 'no-cors'
}).then(function(data){
return data.json()
}).then(function(data){
dispatch(recieveDataArray(data))
})
}
}
export function fetchDataForReals() {
return (dispatch) => {
return dispatch(fetchData())
}
}
My reducers:
const initialState = {
graphDatas: [],
friendsList : {},
comments: []
}
function addData(state = initialState.graphDatas, action) {
switch(action.type) {
case 'RECIEVE_DATA':
var clone = _.cloneDeep(state);
var resultPopOff = clone.pop()
let stateResult = _.isEqual(resultPopOff, action.data)
if (stateResult) {
return state
} else {
return [
...state, action.data
]
}
default:
return state;
}
}
const payment = (state = initialState, action) => {
switch(action.type) {
default:
return {
graphDatas: addData(state.graphDatas, action)
}
}
}
const rootReducer = combineReducers({
payment, routing: routerReducer
})
export default rootReducer
Upvotes: 1
Views: 945
Reputation: 4863
I think where you're doing this in your reducer:
return [
...state, action.data
]
You should be returning the clone that you pop()
ed off:
return [
...clone, action.data
]
Upvotes: 1