简体   繁体   English

Redux状态不更新数组

[英]Redux state not updating array

I have an issue with my redux. 我的redux有问题。 This is the first time I am using it in React. 这是我第一次在React中使用它。 I have managed to successfully use it for logging and registering users. 我已经成功地将其用于登录和注册用户。 However, I have an array of objects created on backend which I am fetching with axios. 但是,我在后端使用axios提取了一系列对象。 Axios logs the data and my action creator also logs data in payload. Axios记录数据,我的动作创建者也将数据记录在有效负载中。 However, it does not update my new state. 但是,它不会更新我的新状态。 I have no idea what I'm doing wrong as I tried it exactly the same way as with my login and register states, however these were only boolean values. 我不知道我在做什么错,因为我尝试的方式与登录和注册状态完全相同,但是这些只是布尔值。 I have googled and searched for a solution. 我已经用谷歌搜索了解决方案。 I tried mapping new array, Object.assign and many others but I can't seem to get it working. 我尝试映射新数组,Object.assign和许多其他对象,但似乎无法正常工作。 Is there any special way on creating new array in state? 在状态下创建新数组是否有任何特殊方法? or can I just assign it action.payload? 还是可以给它分配action.payload? I appreciate all help 我感谢所有帮助

// store.js // store.js

import { applyMiddleware, createStore } from 'redux';
import logger from 'redux-logger';
import thunk from 'redux-thunk';

import reducer from './reducers/reducer';

const middleware = applyMiddleware(logger, thunk);

export default createStore(reducer, middleware);

// rootReducer.js // rootReducer.js

import { combineReducers } from 'redux';

import registerReducer from './registerReducer';
import loginReducer from './loginReducer';
import productsReducer from './products';

export default combineReducers({
  registerReducer,
  loginReducer,
  productsReducer
});

// productsReducer // I believe sth must be wrong here // productsReducer //我相信这里一定是错的

import { SHOW_PRODUCTS, SELECT_PRODUCT } from '../actions/products';

const initialState = {
  productsList: []
};

const productsReducer = (state = initialState, action) => {
  switch (action.type) {
    case SHOW_PRODUCTS: 
      return {...state, productsList: action.payload}
  }
  return state;
}

export default productsReducer;

// actions.js // actions.js

import { SHOW_PRODUCTS, SELECT_PRODUCT } from './constants';

export function showProducts(products) {
  return {
    type: SHOW_PRODUCTS,
    payload: products
  };
}

// component.js // component.js

import React, { Component } from 'react';
import axios from 'axios';
import { connect } from 'react-redux';

import ProductsList from './ProductsList';
import { showProducts }  from '../actions/products';


class Home extends Component {
  constructor(props) {
    super(props);
  }

  componentWillMount() {
    this.props.getProducts(); 
  }

  render() {
    return(
      <div>Home Page
        <ProductsList />
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    productsList: state.productsReducer.productsList
  };
}

const mapDispatchToProps = (dispatch) => {
  return {
    getProducts: () => {
      axios.get('http://localhost:5000/product/list')
      .then((res) => {
        console.log(res.data);
        dispatch(showProducts(res.data))
      })
      .catch(err => console.log(err))
    }
  }
}

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

I am also including a link to an image with my redux logger. 我的redux记录器中还包含指向图像的链接。

https://i.stack.imgur.com/bTnYh.png https://i.stack.imgur.com/bTnYh.png

There's probably a very small, stupid mistake in here as I'm quite new to React and completely new to Redux 这可能是一个很小的愚蠢错误,因为我是React的新手,也是Redux的新手

You have a mistake, and I don't know if you a linter but in productsReducer.js you are importing constants from actions when it should be from constants : 您有一个错误,我不知道您是否是一个lint,但是在productsReducer.js您应该从actions中导入constants ,而constants应该从constants中导入:

import { SHOW_PRODUCTS, SELECT_PRODUCT } from '../actions/constants'; // <- from constants instead

const initialState = {
  productsList: []
};

const productsReducer = (state = initialState, action) => {
  switch (action.type) {
    case SHOW_PRODUCTS: 
      return {...state, productsList: action.payload}
  }
  return state;
}

export default productsReducer;

So your reducer shouldn't be actually taken the proper case since it is undefined and It will so return the initial state. 所以,你的reducer不应该实际采取适当的case ,因为它是undefined ,它会那么回事初始状态。

I believe in mapStateToProps you're going to want to do the following: 我相信mapStateToProps您将要执行以下操作:

const mapStateToProps = (state) => {
    return {
        productsList: state.productsList
    };
}

To confirm productsList being passed through, can you add in a simple loop to the render function of component.js like below: 为了确认productsList是否通过,您可以像下面这样在component.jsrender函数中添加一个简单的循环:

render() {
    const { productsList } = this.props;
    return(
        <div>
            Home Page
            {productsList.map((product, index) => (
                <div key={index}>{product.PROPERTY_NAME_HERE}</div>
            ))}
        </div>
    )
}

The way I do it with my reducer is 我用减速器做的方式是

import { SHOW_PRODUCTS, SELECT_PRODUCT } from '../actions/products';

const initialState = {
  productsList: []
};

const productsReducer = (state = initialState, action) => {
  switch (action.type) {
    case SHOW_PRODUCTS:
      let nextState = {...state};
      nextState.productsList = action.payload
      return nextState;
  }
  return state;
}

export default productsReducer;

Try this way: 尝试这种方式:

componentWillMount() {
  this.getProducts(); 
}

getProducts() {
  axios.get('http://localhost:5000/product/list')
  .then((res) => {this.props.showProducts(res.data);})
  .catch(err => console.log(err));
}

const mapDispatchToProps = dispatch => ({
  showProducts: (data) => {
    dispatch(showProducts(data));
  },
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM