状态似乎被覆盖而不是合并 [英] State seems to be getting overwritten instead of merged

查看:78
本文介绍了状态似乎被覆盖而不是合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试学习 Redux,我想我一定是错误地实现了它,因为只有在页面上呈现的最后一个组件才真正起作用.我怀疑状态每次都被覆盖.

I'm currently trying to learn Redux and I think I must be implementing it wrong as only the last component to be rendered on the page actually works. I suspect the state is being overwritten each time.

我遵循了 this 教程,该教程仅使用了一个数据检索示例,因此我可能已经只是误解了如何写入状态.

I followed this tutorial which only uses one example of data retrieval so I have probably just misunderstood how to write to the state.

这是我的减速机.任何想法我哪里出错了?此外,这一切似乎都很冗长,有没有一种 DRYer 的方式来写出来?

Here is my reducer. Any ideas where I've gone wrong? Also this all seems very verbose, is there a DRYer way of writing this out?

import Immutable from 'seamless-immutable';
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';

// Import actions
import {
  REQUEST_CONFIG,
  GET_CONFIG,
  REQUEST_PAGES,
  GET_PAGES,
  REQUEST_SOCIAL_LINKS,
  GET_SOCIAL_LINKS,
  REQUEST_NAV,
  GET_NAV
} from './actions';

const configInitialState = Immutable({
  items: [],
  isFetching: false
})

const pagesInitialState = Immutable({
  items: [],
  isFetching: false
})

const socialLinksInitialState = Immutable({
  items: [],
  isFetching: false
})

const navInitialState = Immutable({
  items: [],
  isFetching: false
})

export function config(state = configInitialState, action) {
  switch (action.type) {
    case GET_CONFIG :
      return Immutable(state).merge({
        items: action.payload.config[0],
        isFetching: false
      })
    case REQUEST_CONFIG :
      return Immutable(state).merge({
        isFetching: true
      })
    default:
      return state;
  }
}

export function pages(state = pagesInitialState, action) {
  switch (action.type) {
    case GET_PAGES :
      return Immutable(state).merge({
        items: action.payload.pages,
        isFetching: false
      })
    case REQUEST_PAGES :
      return Immutable(state).merge({
        isFetching: true
      })
    default:
      return state;
  }
}

export function socialLinks(state = socialLinksInitialState, action)      {
  switch (action.type) {
    case GET_SOCIAL_LINKS :
      return Immutable(state).merge({
        items: action.payload.socialLinks,
        isFetching: false
      })
    case REQUEST_SOCIAL_LINKS :
      return Immutable(state).merge({
        isFetching: true
      })
    default:
      return state;
  }
}

export function nav(state = navInitialState, action) {
  switch (action.type) {
    case GET_NAV :
      return Immutable(state).merge({
        items: action.payload.nav,
        isFetching: false
      })
    case REQUEST_NAV :
      return Immutable(state).merge({
        isFetching: true
      })
    default:
      return state;
  }
}

const rootReducer = combineReducers({
  config,
  pages,
  socialLinks,
  nav,
  routing: routerReducer
});

export default rootReducer;

以防万一,这里也是我的一个组件的示例:

Just in case it's required, here is an example of one of my components as well:

import React from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { navLoad } from '../../../scripts/actions';

export default class HeaderNav extends React.Component {
  componentWillMount() {
    const { dispatch } = this.props;
    dispatch(navLoad());
  }

  render() {
    const { nav } = this.props;
    const navitems = nav && nav.items ? nav.items.asMutable().map((item) => {
      if(item.inNav === 'header' || item.inNav === 'both') {
        return <li key={item._id}><Link to={item.slug}>{item.name}</Link></li>
      }
    }) : null;
    if(nav.isFetching) {
      return(
        <section class="loader">
          <span>Content is loading...</span>
        </section>
      )
    } else {
      return(
        <nav class="c-primary-nav">
          <span class="c-primary-nav_toggle">Menu</span>
          <ul>
            { navitems }
          </ul>
        </nav>
      )
    }
  }
}

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

export default connect(select)(HeaderNav);

这里是调用组件的地方:

and here is where the components are called:

import React from 'react';
import HeaderNav from './Header/nav.jsx';
import SocialLinks from './Header/socialLinks.jsx';

export default class Header extends React.Component {
  render() {
    return(
      <header class="c-global-header" role="banner">
        <HeaderNav />
        <SocialLinks />
      </header>
    )
  }
}

更新:我仍然希望得到这个问题的答案,因为它仍然困扰着我,我现在稍微修改了代码但无济于事.您可以在此处查看我的完整代码库:https://github.com/alexward1981/portfolio-react(所有相关的东西都在'src'文件夹中)

Update: I'm still hoping for an answer to this question as it's still stumping me, I've altered the code a little now but to no avail. You can see my full codebase here: https://github.com/alexward1981/portfolio-react (All the relevant stuff is in the 'src' folder)

推荐答案

我刚刚遇到了同样的问题,问题出在减速器上,而不是在默认的 switch case 部分返回 state,我是 return initialState.

I just faced the same problem, the issue was in the reducer, instead of return state in default switch case section, I was return initialState.

export const getAppShopReducer = (state = initialState, action) => {
  switch (action.type) {
    case types.FETCH_APP_SHOP_SUCCESS:

      return state
        .set('loading', false)
        .set('user', action.payload.user)
        .set('appShop', action.payload.appShop)
        .set('shop', action.payload.shop)
        ;

    case types.FETCH_APP_SHOP_REQUEST:

      return initialState.set('loading', true);

    default:
      return state; // Here's the problem, it was `initialState`;
  }
};

这篇关于状态似乎被覆盖而不是合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆