无法读取Reducer Redux中未定义的属性“数据”

时间:2019-10-02 13:28:18

标签: javascript reactjs redux react-redux

我在reducers中有一个问题想要尝试分配todos: action.payload.data。我有错误:

  

无法读取未定义错误的属性“数据”。

const rootReducer = (state = initialState, action) => {
      switch (action.type) {
        case 'GET_TODOS':
          return {
            ...state,
            todos: action.payload.data
          };

        default:
          return state;
      }
    };

此处演示:https://stackblitz.com/edit/react-ewpquh

动作

import axios from 'axios';

export const GET_TODOS = 'GET_TODOS';
export const FETCH_SUCCESS = 'FETCH_SUCCESS';
export const FETCH_FAILURE = 'FETCH_FAILURE';

export const getTodos = () => 
dispatch => {
  dispatch({type: GET_TODOS});

  return axios({
      url: 'https://jsonplaceholder.typicode.com/todos',
      method: 'GET',
    })
    .then(data => {
      console.log(data);

      dispatch({type: FETCH_SUCCESS, payload:{
        data 
      }});

    })
    .catch(error => {
      console.log(error);

      dispatch({type: FETCH_FAILURE})
    });
};

Todos

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {getTodos} from '../.././actions';

class Todos extends Component {
  componentDidMount() {
    this.props.getTodos(); 
  }

  render() {
    return (
      <ul>
        {this.props.todos.map(todo => {
        return <li key={todo.id}>
                  {todo.title}
               </li>
         })}
      </ul>
    );
  }
}

const mapStateToProps = state => {
  console.log(state.todos);
  const { todos } = state;

  return {
    todos
  };
};

const mapDispatchToProps = dispatch => ({
  getTodos: () => dispatch(getTodos())
});

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

减速器

import {GET_TODOS} from '../../actions';

const initialState = {
  todos: []
};

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'GET_TODOS':
      return {
        ...state,
        todos: action.payload.data
      };

    default:
      return state;
  }
};

export default rootReducer;

商店

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store;

5 个答案:

答案 0 :(得分:1)

即将出现的错误是关于GET_TODOS动作类型的,请查看您的动作(索引文件),您在分派GET_TODOS时没有传递有效载荷对象。

此外,您正在传递一个名为FETCH_SUCCESS的动作,但是在减速器中没有任何用例。您是否打算在这里调度GET_TODO?

答案 1 :(得分:1)

检查您的 actions.js

 dispatch({type: GET_TODOS});

您不会在此调度中传递任何有效负载,可能其 FETCH_SUCCESS 需要放在减速器中,而不是 GET_TODOS

答案 2 :(得分:1)

您的actions / index.js文件应为:

    Word.Document doc = wdApp.ActiveDocument;
    Word.Style sOld = null;
    Word.Style sCopy = null;
    Word.Find f = doc.Content.Find;

    //Select Normal text, otherwise Normal will take on character formatting of current selected text
    Word.Selection sel = wdApp.Selection;
    sel.Find.set_Style(Word.WdBuiltinStyle.wdStyleNormal);
    sel.Find.Execute("", Type.Missing,
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, true, Word.WdFindWrap.wdFindStop,
      true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    foreach (Word.Style s in doc.Styles)
    {
        if ((s.InUse) && (s.Type == Word.WdStyleType.wdStyleTypeParagraph) && 
            (!s.NameLocal.Contains(" Copy")))
        {
            sOld = s;
            sCopy = doc.Styles.Add(sOld.NameLocal + " Copy", sOld.Type);
            sCopy.set_BaseStyle(sOld);
            f.set_Style(sOld);
            f.Replacement.set_Style(sCopy);
            f.Execute("", Type.Missing, 
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, true, Word.WdFindWrap.wdFindStop, 
            true, "", Word.WdReplace.wdReplaceAll, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        }
    }

reducers / index.js文件应为:

import axios from 'axios';

export const GET_TODOS = 'GET_TODOS';
export const FETCH_SUCCESS = 'FETCH_SUCCESS';
export const FETCH_FAILURE = 'FETCH_FAILURE';

export const getTodos = () => 
 dispatch => {
  dispatch({type: GET_TODOS});

   axios({
      url: 'https://jsonplaceholder.typicode.com/todos',
      method: 'GET',
    })
    .then(response => {
      console.log(response.data);
      const data = response.data;
      dispatch({type: FETCH_SUCCESS, payload:{
        data 
      }});

    })
    .catch(error => {
      console.log(error);
      dispatch({type: FETCH_FAILURE})
    });
};

答案 3 :(得分:0)

函数'GET_TODOS'在未履行承诺的情况下被触发并执行而没有发送payload,函数'GET_TODOS'必须在履行承诺时执行,以便能够发送{ {1}} payload,函数getTodos将保持以下方式:

'data'

答案 4 :(得分:0)

首先,您应该将大小写FETCH_SUCCESS添加到reducer:

 case 'FETCH_SUCCESS':
  return {
    todos: action.payload.data
  };

之后,您需要在操作文件上替换此代码:

 .then(result => {
  const data = result.data

  dispatch({type: FETCH_SUCCESS, payload:{
    data
  }});

})

最后,检查TodosList在组件上是否为空:

return (
  <ul>
    {this.props.todos && this.props.todos.map(todo => {
    return <li key={todo.id}>
              {todo.title}
           </li>
     })}
  </ul>
);