Reactjs React/Redux不';t正确更新状态并可以';不能在组件中使用

Reactjs React/Redux不';t正确更新状态并可以';不能在组件中使用,reactjs,redux,react-redux,material-ui,connect,Reactjs,Redux,React Redux,Material Ui,Connect,我是React和Redux新手,一直遵循官方的Redux docs Todo List示例,最近修改了代码,以遵循presentational/container components结构。我尝试了许多不同的方法来移动API调用,但通常情况下,状态中的权重对象显示为未定义(可能是因为它试图在实际API调用之前使用,但我不知道如何从现在的位置更改API调用) 以下是文件: actions/index.js import axios from 'axios'; export const getWe

我是React和Redux新手,一直遵循官方的Redux docs Todo List示例,最近修改了代码,以遵循presentational/container components结构。我尝试了许多不同的方法来移动API调用,但通常情况下,状态中的权重对象显示为未定义(可能是因为它试图在实际API调用之前使用,但我不知道如何从现在的位置更改API调用)

以下是文件:

actions/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'
}
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)
减速机/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 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'
}
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)
目前,我通过导入相应的分派操作并使用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调用正确,但不知道如何更改组件才能正确显示。**Wh如果我尝试调用组件而不是组件,我会得到错误:“TypeError:无法读取未定义的”***

的属性“map”,因为您在
reducers/weights.js中将
权重声明为初始状态下的空数组
[]

您正在对其进行如下分解

const { weights } = this.props.weights;
由于您声明的权重是未定义的
,因此您得到的是错误

TypeError: Cannot read property 'map' of undefined
因此,请尝试根据您的确切要求进行更改

确保所有代码在没有数据的情况下都能工作,因为整个组件在API调用之前被呈现,所以要么处理组件以使用空数据呈现,要么确保代码在获取API数据之前不会发出声音

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

文件
组件/项目/index.js

render
函数中更改以下行

const { weights } = this.props.weights;


components/Items/index.js
中,您正在将
weights
作为一个对象进行分解,但在初始状态下,您将其声明为空数组并用于注释,我感谢您的快速响应!但是,此更改仍然不允许显示VisibleWeights组件而不是WeightItems组件。我不明白我已经显示的代码中的未定义的类型错误,但是在组件/项目/索引中用VisualBooad替换重量级组件时,得到它。jSCAN您创建一个应用程序的代码框,以便更好地调试。今天我会尝试把一个放在一起,谢谢您的帮助!哇,在我创建代码沙箱的过程中,我意识到了。我正在映射的返回对象有一个子组件,该子组件具有相同的名称,包含来自数据库的每个数据数组。即使没有显示沙盒,您也引导我找到了答案,我对此表示感谢!
const { weights } = this.props.weights;
const { weights = [] } = this.props;