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