同一组件的多个实例会覆盖彼此的状态/道具

时间:2017-01-09 11:44:07

标签: javascript reactjs redux state

我正在编写一个跟踪器来跟踪我们每只猫的喂食时间。它对我们的第一只猫来说非常有效,但当我添加第二只猫时,我注意到只有第二只猫的状态被存储并且正在覆盖第一个组件状态。

我不确定我哪里出错了,因为我觉得反应中的每个组件都是独立的。

以下是组件的代码:

import React from 'react';
import { connect } from 'react-redux';
import { kittyFeedLoad, kittyFeedPost } from '../../scripts/components/kittyfed';

export class KittyFed extends React.Component {
  componentWillMount() {
      const { dispatch } = this.props;
      dispatch(kittyFeedLoad(this.props.kitty));
      setInterval(() => dispatch(kittyFeedLoad(this.props.kitty)), 120000);
  }

 render() {
   const { kittyFeed } = this.props

if(kittyFeed.isFetching) {
  return (
    <section class="c-module c-module_kitty-fed">
      <p>Getting info from servers</p>
    </section>
  )
} else {
  let feedCount = kittyFeed.items.feedCount;
  let status = '';
  switch (feedCount) {
    case 0:
      status = 'sad'
      break;
    case 1:
      status = 'content'
      break;
    case 2:
      status = 'happy'
      break;
    default:
      status = 'super_happy'
  }

  return(
    <section class={"c-module c-module_kitty-fed " + status + " cat_"+this.props.kitty}  onClick={ kittyFeedPost }>
      <div class="c-module_kitty-fed__last-fed">
        <span>{ this.props.kitty } was last fed { kittyFeed.items.fedDay } at </span>
        <span class="c-module_kitty-fed__feed_log">
          { kittyFeed.items.lastFed }
        </span>
      </div>
      <div class="c-module_kitty-fed__status">
        <span> She has been fed <strong>{ feedCount }</strong> time(s) today. </span>
      </div>
    </section>
  )
}

  }
}

function select(state) {
  const { kittyFeed } = state;
  return {
    kittyFeed
  };
}

export default connect(select)(KittyFed);

减少者和行动

import axios from 'axios';
import immutable from 'seamless-immutable';
import moment from 'moment';
import 'moment/locale/en-gb';

/******************
  Actions
******************/

export const REQUEST_KITTY_FEED = 'REQUEST_KITTY_FEED';
export const GET_KITTY_FEED = 'GET_KITTY_FEED';

// Kitty feed status
export function requestKittyFeed() {
  return {
    type: REQUEST_KITTY_FEED
  };
}

export function getKittyFeed(json) {
  let getLastFed = () => {
    let item = '';
    for (var i = 0; i < json.length; i++) {
      item = json[i].Time
    }
    return item;
  }

  let getFedDay = () => {
    let item = '';
    for (var i = 0; i < json.length; i++) {
     item = json[i].Date
    }
    let today = moment().format('L');
    let yesterday = moment().subtract(1, 'days').format('L');

    if (item === today) {
      // Kitty was fed today
      return 'Today'
    } else if (item === yesterday) {
      // Kitty was fed yesterday
      return 'Yesterday'
    } else {
      // Kitty hasn't been fed in days, we'd best work out how long it's been
      return moment(item, 'L').fromNow();
    }
  }

  let getTodaysCount = () => {
    let fedToday = [];
    for (var i = 0; i < json.length; i++) {
      if(json[i].Date === moment().format('L')) {
        fedToday.push(json[i].Date);
      }
    }
    return fedToday.length;
  }

  const todaysData = {
    fedDay : getFedDay(),
    lastFed : getLastFed(),
    feedCount : getTodaysCount()
  }

  return {
    type: GET_KITTY_FEED,
    payload: {
      kittyFeed: todaysData,
      receivedAt: Date.now()
    }
  };
}

// thunk actions
export function kittyFeedLoad(cat) {
  return dispatch => {
    dispatch(requestKittyFeed());
    return axios.get('[data feed url]')
    .then(function(response) {
      let data = response.data.Sheet1;
      let filteredData = data.filter(function(c) {
        return c.Cat === cat;
      })
      dispatch(getKittyFeed(filteredData))
    })
  }
}

// thunk actions
export function kittyFeedPost() {
  return axios.post('https://api.cloudstitch.com/alexward1981/kitty-fed-times', {
      Date: moment().format('L'),
      Time: moment().format('HH:mm')
    })
}

/******************
  Reducers
******************/

const initialState = immutable({
  items: [],
  isFetching: false
})

export function kittyFeed(state = initialState, action) {
  switch (action.type) {
    case GET_KITTY_FEED :
      return immutable(state).merge({
        items: action.payload.kittyFeed,
        isFetching: false
      })
    case REQUEST_KITTY_FEED :
      return immutable(state).merge({
        isFetching: true
      })
    default:
      return state;
  }
}

0 个答案:

没有答案