2017-01-21 7 views
1

Я использую Redux + реагирующие построить свой веб-сайт, и я хочу использовать Redux для управления боковой панели visible.The боковой панель определяются семантическим-интерфейс реагирует .Потому что я хочу управлять им по другому компоненту, поэтому я определил реквизиты в родительском компоненте боковой панели const { visible, dispatch } = this.props, есть функция onClick, чтобы справиться с этим. Я покажу свой код.Redux действие должно быть простыми объектами, но я определил простой объект

Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.

Эта ошибка смутила меня однажды днем, и я не знаю почему! Это мой код действия:

**action** 

export const SIDEBARISVISIBLE = 'sidebarVisible' 

export function sidebarVisibleAction() { 
    return { type: SIDEBARISVISIBLE } 
} 

Как вы можете видеть, я определил, что создатель действия возвратил простой объект.

И это мой редуктор код:

**reducer** 

import SIDEBARISVISIBLE from '../actions/outside.js' 

function sidebarVisible(state = { 
    sidebarIsVisible: false 
}, action) { 

    switch (action.type) { 
     case SIDEBARISVISIBLE: 
      return Object.assign({}, state, { 
       sidebarIsVisible: !state.sidebarIsVisible 
      }) 
     default: 
      return state 
    } 
} 

export default sidebarVisible 

Также мой магазин код:

**store** 

import { createStore, applyMiddleware, compose } from 'redux' 
import thunk from 'redux-thunk' 
import sidebarVisible from '../reducers/outside.js' 

export default initialState => { 
    return createStore(
    sidebarVisible, 
    initialState, 
    applyMiddleware(thunk) 
) 
} 

Тогда мой код компонента (часть):

class OutsideView extends Component { 

    constructor(props) { 
     super(props) 
     this.state = { activeItem: '' } 
    } 

    handleItemClick = (e, { name }) => this.setState({ activeItem: name }) 

    render() { 
     const { activeItem } = this.state 
     const { visible, dispatch } = this.props 

     return (
      <div> 
       <SidebarNav visible={ visible } /> 

       ...... 

        <Menu.Item 
        name='sidebar' 
        active={ activeItem === 'sidebar'} 
        onClick={ (e, {name}) => { 
           this.setState({ activeItem: name }) 
           dispatch(sidebarVisibleAction) 
          } }> 
        <Icon color='red' name='list' /> 
       </Menu.Item> 

OutsideView.PropTypes = { 
    visible: PropTypes.bool.isRequired, 
    dispatch: PropTypes.func.isRequired 
} 

function mapStateToProps(state) { 
    return { 
    visible: state.sidebarIsVisible, 
    } 
} 

export default connect(
    mapStateToProps 
)(OutsideView) 

Последнее, мой Маршрутизатор:

import configureStore from './store/index.js' 
const store = configureStore() 

export default class Root extends Component { 

    render() { 
     return (
      <Provider store={ store }> 
      <Router history={ browserHistory }> 
       <Route path="/" component={ OutsideRedux }> 
        <Route path='register' component={ Register } /> 
        <Route path='login' component={ Login } /> 
        <Route path='blog' component={ Blog } /> 
        <Route path='about' component={ About } /> 
        <Route path='home' component={ Home } /> 
        <Route path='ask' component={ Ask } /> 
        <Route path='panel' component={ Panel } /> 
        <Route path='setting' component={ Setting } /> 
        <Route path='user' component={ User } /> 
       </Route> 
      </Router> 
      </Provider> 
     ) 
    } 
} 

Итак, я ищу ответ на эту ошибку, большинство из них говорит, вы должны установить Redux-стук и с ApplyMiddleware использовать его, самое простое way.But действия я определил это обычного объект .Ело Я не использую redux-thunk, я думаю, что я тоже не буду сталкиваться с этой ошибкой. Итак, я очень смущен, как это решить?

Спасибо за помощь

+0

Не уверен, что это связано, поэтому я пишу это как комментарий. Почему вы используете 'dispatch'? Вы должны использовать 'mapDispatchToProps' в [' connect'] (https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options) и получить действие как 'this.props.actionName'. Просто убедитесь, что вы используете версию реквизита, а не импортированную. Сделал эту ошибку слишком много раз: D –

+0

Также общий комментарий о вашем коде, зачем использовать состояние компонента, если вы уже используете redux? Если вы используете redux, лучше всего управлять всеми состояниями с помощью redux, код проще рассуждать и проще тестировать. Дополнительный бонус заключается в том, что таким образом вам не нужен класс, вы можете использовать чистый компонент. –

+0

@ MarkoGrešak Да, я объясню, что вы сказали. Во-первых, я использую ** отправку **, потому что я ссылаюсь на официальный код Reddit Reddit API. В то же время, состояние, которое я использую, просто для активного элемента, это семантически- ui-реагировать по умолчанию, поэтому я не изменю его. – g1eny0ung

ответ

9

Здесь:

dispatch(sidebarVisibleAction)

вы передаете функцию sidebarVisibleAction к dispach. Вы должны вызвать его и передать результат, так что код будет выглядеть следующим образом:

dispatch(sidebarVisibleAction())

(теперь dispatch получит объект, а не функция).

+0

Отличный улов. Я смотрел на это, когда в поисках ответа, но как-то пропустил его. Автору (который упомянул, что они относятся к официальному примеру Reddit API), это можно увидеть здесь: http://redux.js.org/docs/advanced/ExampleRedditAPI.html#containersasyncappjs –

+1

Да, это ответ! Спасибо! Но я меняю свой код. Я обнаружил новую ошибку: (0, _outside2.default) не является функцией. И спасибо за @ MarkoGrešak, я думаю, что вы правы, я меняю свой код на использование ** mapDispatchToProps ** и подключаю его. Я пытаюсь решить новую ошибку. – g1eny0ung

+0

@ g1eny0ung это выглядит как неправильное использование 'import' и/или' export'. Трудно сказать, где, потому что вы, кажется, не включили весь код. Если вы не осознаете это самостоятельно, задайте новый вопрос. –