繁体   English   中英

React/Redux 无法正确更新状态且无法在组件中使用

[英]React/Redux Doesn't Update State Properly and Can't Be Used in Component

我是 React 和 Redux 的新手,一直在关注官方 Redux 文档待办事项列表示例https://redux.js.org/basics/example ,最近更改了我的代码以遵循演示/容器组件结构。 我尝试了许多不同的移动 API 调用的方法,但状态中的权重对象经常显示为未定义(可能是因为它试图在进行实际 API 调用之前使用,但我不知道如何从现在的位置更改 API 调用)。

以下是文件:

动作/ index.js

import axios from 'axios';

export const getWeights = () => dispatch => {
  axios.get('/api/weights')
  .then(res => 
    dispatch({
      type: 'GET_WEIGHTS',
      payload: res.data
    })
  )
}

export const setShownCategory = category => ({
  type: 'SET_SHOWN_CATEGORY',
  category
})

export const Categories = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_ACCESSORIES: 'SHOW_ACCESSORIES',
  SHOW_BARBELLS: 'SHOW_BARBELLS',
  SHOW_DUMBBELLS: 'SHOW_DUMBBELLS',
  SHOW_PLATES: 'SHOW_PLATES',
  SHOW_RACKS: 'SHOW_RACKS',
  SHOW_OTHER: 'SHOW_OTHER'
}

减速器/weights.js

const initialState = {weights: []}

export default function(state = initialState, action) {
  switch (action.type) {
    case 'GET_WEIGHTS':
      return {
        ...state,
        weights: action.payload
      }
    default:
      return state;
  }
}

组件/项目/index.js

import React from 'react';
import CategoryBar from './CategoryBar'

import Typography from '@material-ui/core/Typography';
import { connect } from 'react-redux';
import { getWeights } from '../../actions'
import WeightItems from './WeightItems';

class Items extends React.Component {
  componentDidMount() {
    console.log(this.props)
    this.props.getWeights();
  }

  render() {
    const { weights } = this.props.weights;
    return (
      <div>
         <Typography variant="h4">Browse</Typography>
         <div>
           <CategoryBar />
         </div>
         <WeightItems weights={weights} />
       </div>
    )
  }
}

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

export default connect(
  mapStateToProps,
  { getWeights }
)(Items)

组件/项目/WeightItems.js

import React from 'react'

import Grid from '@material-ui/core/Grid';
import { makeStyles } from '@material-ui/core/styles';
import Item from './Item'

const useStyles = makeStyles({
  items: {
    display: 'flex',
    margin: 'auto',
  }
})

const WeightItems = ({ weights }) => {
  const classes = useStyles()

  return (
    <Grid className={classes.items} container direction="row" justify="center" alignItems="center" spacing={3}>
      {weights.map(weight => <Item key={weight.id} weight={weight} />)}
    </Grid>
  )
}

export default WeightItems

组件/项目/Item.js

import React from 'react';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';

const Item = ({ weight }) => {
  return (
    <Grid item xs={12} sm={6} md={4}>
      <Paper>{weight.title}</Paper>
    </Grid>
  )
}

export default Item

商店.js

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

const initialState = {};

const middleWare = [thunk];

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  rootReducer,
  initialState,
  composeEnhancers(applyMiddleware(...middleWare))
);

export default store;

目前,我通过导入相应的调度操作并使用 connect() 来调用 components/Items/index.js 组件中的 API,但是,我需要能够在某处调用 API,而不是这样做并传递权重否则并根据从不同组件中选择的过滤器呈现 VisibleWeights 组件(我没有显示它是因为它正常工作并正确更新状态,但如果需要为上下文显示它,肯定可以添加)。

容器/VisibleWeights.js

import { connect } from 'react-redux'
import { Categories } from '../actions'
import WeightItems from '../components/Items/WeightItems'

const getVisibleWeights = (weights, category) => {
  console.log(weights, category)
  switch(category) {
    case Categories.SHOW_ACCESSORIES:
      return weights.filter(weight => weight.category === 'Accessories')
    case Categories.SHOW_BARBELLS:
      return weights.filter(weight => weight.category === 'Barbells')
    case Categories.SHOW_DUMBBELLS:
      return weights.filter(weight => weight.category === 'Dumbbells')
    case Categories.SHOW_PLATES:
      return weights.filter(weight => weight.category === 'Plates')
    case Categories.SHOW_RACKS:
      return weights.filter(weight => weight.category === 'Racks')
    case Categories.SHOW_OTHER:
      return weights.filter(weight => weight.category === 'Other')
  }
}

const mapStateToProps = state => ({
  weights: getVisibleWeights(state.weights, state.shownCategory)
})

export default connect(
  mapStateToProps,
)(WeightItems)

如果我可以添加任何其他代码或评论,请告诉我。 在过去的两天里,我一直在努力让这个小东西正确,但无法弄清楚需要更改什么才能使其正常工作。 我知道 API 被正确调用,但不知道需要如何更改组件才能正确显示它。 **当我尝试调用组件而不是组件时,出现错误:'TypeError:无法读取未定义的属性'map' **

当您在reducers/weights.js中将weights声明为初始状态的空数组[]

你正在解构它,如下所示

const { weights } = this.props.weights;

因为根据您的声明undefined权重您收到错误

TypeError: Cannot read property 'map' of undefined

所以尝试根据您的确切要求更改它

确保所有代码即使在没有数据的情况下也能正常工作,因为整个组件在 API 调用之前都已渲染,因此要么处理组件以使用空数据进行渲染,并确保您的代码在获取 API 数据之前不会发出声音

根据您的代码,它认为wights是对象数组,因此我认为进行以下更改不会破坏您的应用程序

文件components/Items/index.js

render函数中更改以下行

const { weights } = this.props.weights;

const { weights = [] } = this.props;

暂无
暂无

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

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