【问题标题】:Props not updating when I change the store in react当我在反应中更改商店时道具没有更新
【发布时间】:2020-01-03 21:53:11
【问题描述】:

我有一个问题,当我从 API 获取数据并更新存储时,数据没有改变。它被绑定为道具,我认为它应该改变,我注意到的另一件事是它在商店更新后不会调用 mapStateToProps 。当我给商店一些初始值时,它会显示它,所以我认为它可以看到商店,其他东西显然是错误的,但我不知道是什么。

减速器代码:

import { ADD_POST } from "../actions/addAction";
import { GET_POSTS } from "../actions/getAction";
import { DELETE_POST } from "../actions/deleteAction";
import { UPDATE_POST } from "../actions/updateAction";
import axios from "axios";

const initialState = {
  posts: []
};

export default function postsReducer(state = initialState, { type, payload }) {
  switch (type) {
    case ADD_POST:
      state = state.slice();
      state.push(payload);
      break;
    case GET_POSTS:
      axios
        .get("http://localhost:59511/api/post?date=31-12-2019")
        .then(response => {
          response.data.forEach(thePost => {
            state.posts = [...state.posts, thePost];
          });
          console.log(state.posts);
          return state;
        });
      break;
    default:
      return state;
  }

  return state;
}

索引(这里我创建了我的商店并用提供者包装了应用程序组件):

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { combineReducers, createStore } from "redux";
import { Provider } from "react-redux";

import postReducer from "./reducers/postsReducers";

const allReducers = combineReducers(
  {
    post: postReducer
  },

  window.devToolsExtension && window.devToolsExtension()
);

const store = createStore(allReducers);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.

serviceWorker.unregister();

像这样在我的组件中映射它:

const mapStateToProps = state => ({
  posts: state.post.posts
});

如果你们需要其他任何东西,请告诉我,我有一个文件有点大,所以如果没有必要我不想添加它,我现在正在用头撞墙几个小时.提前致谢

===编辑=== 我还将我的动作映射到道具

const mapActionToProps = {
  onDeletePost: deletePost,
  onUpdatePost: updatePost,
  onGetPost: getPosts
};

我的动作定义为

export const ADD_POST = "posts:addPost";

    export function addPost(newTitle, newHours, newDate) {
      return {
        type: ADD_POST,
        payload: {
          id: new Date().toString(),
          title: newTitle,
          hours: newHours,
          date: new Date().toLocaleDateString()
        }
      };
    }

所以我已经在那里定义了动作,所以我不确定我是否需要 dispatchToAction?在我们说话的时候,我正在查找它,并会尝试做点什么,只是有点困惑。 ==编辑结束==

【问题讨论】:

    标签: reactjs redux frontend state


    【解决方案1】:

    我认为技术上你的问题是你的reducer在提取完成之前返回(在所有axios之后)。但这不是您要解决的问题。

    首先,你的 reducer 中发生了太多事情。您不应该在 reducer 中实现操作(获取数据)。我想在你的组件中你正在构建一个看起来像{type: 'GET_POSTS'} 的动作,然后......调度它?除非您似乎没有为您的组件提供调度。所以行动永远不会到达商店。我只能假设,因为您没有向我们展示您从哪里调用您的操作。

    您应该将您的获取转移到它自己的异步(thunk)操作方法:

       function getPosts() {
         return dispatch => {
           axios
            .get("http://localhost:59511/api/post?date=31-12-2019")
            .then(response => {
              const posts = response.data
              dispatch({type: 'GET_POSTS', payload: posts})
            });
         }
       }
    

    然后只需将帖子添加到您的减速器中的状态:

    
    export default function postsReducer(state = initialState, { type, payload }) {
      switch (type) {
        case GET_POSTS:
         return { ...state, posts: payload }
        default:
          return state;
      }
    

    然后您必须使用mapDispatchToPropsgetPosts() 函数连接到您的商店。而且你还必须使用redux-thunk,否则这根本行不通。

    您在 react-redux 方面有了一个良好的开端,但您的学习还存在一些差距。您将需要研究异步操作和 redux thunk(或其他一些异步操作中间件)。我建议查看所有 Redux 文档,主要是 advanced tutorials


    【讨论】:

      【解决方案2】:

      您的 reducer 处于变异状态,这会破坏应用程序。

      此外,您正在reducer 中进行AJAX 调用,这是从不 允许的。所有异步逻辑都发生在reducer 之外,并且reducer查看它们的stateaction 参数来计算新状态。

      这就是为什么 Redux 样式指南的前两条“基本”规则是 Do Not Mutate StateReducers Must Not Have Side Effects

      强烈建议您使用our new official Redux Toolkit package。它的configureStore() 函数默认设置突变检测,它具有createSlice() 等功能,可以让您编写更简单的不可变更新逻辑。

      除此之外,我建议您花更多时间阅读 Redux 文档,以了解您应该如何正确使用 Redux。

      【讨论】:

      【解决方案3】:

      我将我的行为改为

      import axios from "axios";
      export const GET_POSTS = "posts:getPosts";
      
      export function getPosts(theDate) {
        return dispatch => {
          axios
            .get("http://localhost:59511/api/post?date=31-12-2019")
            .then(response => {
              const posts = response.data;
              dispatch({ type: GET_POSTS, payload: posts });
            });
        };
      }
      

      减速器:

      import { ADD_POST } from "../actions/addAction";
      import { GET_POSTS } from "../actions/getAction";
      import { DELETE_POST } from "../actions/deleteAction";
      import { UPDATE_POST } from "../actions/updateAction";
      
      const initialState = {
        posts: []
      };
      
      export default function postsReducer(state = initialState, { type, payload }) {
        switch (type) {
          case ADD_POST:
            state = state.slice();
            state.push(payload);
            break;
          case GET_POSTS:
            payload.forEach(element => {
              state.posts = [...state.posts, element];
            });
      
            break;
          default:
            return state;
        }
      
        return state;
      }
      

      在我想要显示帖子的组件中:

      const mapStateToProps = state => ({
        posts: state.post.posts
      });
      

      然后显示:

       render() {
           return (
             <div className="contentWindow">
               {this.props.posts.map((post, i) => {
                 return (
                 #some displaying logic
      

      使用中间件更改存储创建:

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

      仍然没有更新我将状态映射到道具的组件中的道具。 当我使用 react 开发工具检查商店时,正在进行更改,但我的一些道具没有更新。

      =====编辑===== 我已将减速器代码更改为:

      import { ADD_POST } from "../actions/addAction";
      import { GET_POSTS } from "../actions/getAction";
      import { DELETE_POST } from "../actions/deleteAction";
      import { UPDATE_POST } from "../actions/updateAction";
      
      const initialState = {
        posts: [123]
      };
      
      export default function postsReducer(state = initialState, { type, payload }) {
        switch (type) {
          case ADD_POST:
            state = state.slice();
            state.push(payload);
            break;
          case GET_POSTS:
            return { ...state, posts: payload };
      
          case DELETE_POST:
            state = state.filter(post => post.id !== payload.id);
            break;
          case UPDATE_POST:
            for (let index = 0; index < state.length; index++) {
              if (state[index].id === payload.theId) {
                state[index].id = payload.theId;
                state[index].date = payload.newDate;
                state[index].hours = payload.newHours;
                state[index].title = payload.newTitle;
              }
            }
      
            break;
          default:
            return state;
        }
      
        return state;
      }
      

      现在我有一个问题,它每次 xD 都会改变它的初始状态,我很高兴我设法通过前一个,顺便说一句,现在感觉如此强大:D。

      【讨论】:

        猜你喜欢
        • 2021-09-05
        • 1970-01-01
        • 1970-01-01
        • 2020-08-11
        • 2016-06-25
        • 2019-12-08
        • 2017-05-31
        • 2021-12-28
        • 2022-07-18
        相关资源
        最近更新 更多