提问人:bigmacreact 提问时间:11/13/2023 更新时间:11/14/2023 访问量:60
react store 和 redux 的问题 - 显示正确,但编辑导致错误
Problem with react store and redux - shows properly but editing cause error
问:
我正在创建基于 store 和 react redux 的 react 应用程序,它们从 json 文件中获取数据。我有一个问题,我创建了所有结构并且它显示正确,但是当我尝试编辑一些数据时,它显示错误:state.properties.map 不是一个函数 我不完全了解 store 和 redux 是如何工作的,这就是为什么我需要你的帮助来找到问题所在,你能帮我吗?
还原剂:
import { UPDATE_PROPERTY } from "./actions";
import data from "./data.json"; // Importuj dane z pliku data.json
const initialState = {
properties: data, // Ustaw dane z data.json jako początkowy stan properties
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case UPDATE_PROPERTY:
const updatedProperties = state.properties.map((prop) =>
prop.name === action.payload.name ? action.payload : prop
);
return { ...state, properties: updatedProperties };
default:
return state;
}
};
export default rootReducer;
商店:
import { configureStore } from "@reduxjs/toolkit";
import rootReducer from "./reducers";
const store = configureStore({
reducer: {
data: rootReducer,
},
});
export default store;
行动:
export const UPDATE_PROPERTY = 'UPDATE_PROPERTY';
export const updateProperty = (property) => ({
type: UPDATE_PROPERTY,
payload: property,
});
索引.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./store";
import App from "./App";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
财产:
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import TextField from "@material-ui/core/TextField";
import Checkbox from "@material-ui/core/Checkbox";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { updateProperty } from "./actions";
const Property = ({ property }) => {
const dispatch = useDispatch();
const [editedProperty, setEditedProperty] = useState(property);
const handleBlur = () => {
dispatch(updateProperty(editedProperty));
};
const handleChange = (event) => {
const { name, value, type, checked } = event.target;
const newValue = type === "checkbox" ? checked : value;
setEditedProperty({
...editedProperty,
[name]: newValue,
});
};
return (
<div>
<h3>{property.name}</h3>
{property.type === "text" && (
<TextField
name="value"
value={editedProperty.value}
onBlur={handleBlur}
onChange={handleChange}
/>
)}
{property.type === "checkbox" && (
<FormControlLabel
control={
<Checkbox
name="value"
checked={editedProperty.value}
onBlur={handleBlur}
onChange={handleChange}
/>
}
label="Check"
/>
)}
{property.type === "combobox" && (
<Autocomplete
options={property.options}
name="value"
value={editedProperty.value}
onBlur={handleBlur}
onChange={(event, newValue) => {
handleChange({ target: { name: "value", value: newValue } });
}}
freeSolo
renderInput={(params) => <TextField {...params} />}
/>
)}
</div>
);
};
export default Property;
应用程序:
import React from "react";
import { useSelector } from "react-redux";
import Property from "./Property";
import Accordion from "@mui/material/Accordion";
import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
function App() {
const properties = useSelector((state) => state.data.properties);
const groupedProperties = {};
properties.properties.forEach((property) => {
if (!groupedProperties[property.group]) {
groupedProperties[property.group] = [];
}
groupedProperties[property.group].push(property);
});
return (
<div className="App">
{Object.entries(groupedProperties).map(([groupName, groupProperties]) => (
<Accordion key={groupName}>
<AccordionSummary>{groupName}</AccordionSummary>
<AccordionDetails>
<div>
{groupProperties.map((property) => (
<Property key={property.name} property={property} />
))}
</div>
</AccordionDetails>
</Accordion>
))}
</div>
);
}
export default App;
这就是我使用的所有组件,如果您看到(很可能是)我所做的一些不良做法或愚蠢的解决方案 - 如果您指出它们,我将不胜感激。
答:
0赞
hcharles25
11/13/2023
#1
默认情况下,属性未定义。.map 不能与 undefined 一起使用。
尝试使用它
const updatedProperties = state.properties ? state.properties.map((prop) =>
prop.name === action.payload.name ? action.payload : prop
) : [];
评论
0赞
bigmacreact
11/13/2023
我确实尝试过这个,但我仍然遇到同样的错误
0赞
Drew Reese
11/14/2023
#2
基于组件中的代码App
const properties = useSelector((state) => state.data.properties);
const groupedProperties = {};
properties.properties.forEach((property) => {
if (!groupedProperties[property.group]) {
groupedProperties[property.group] = [];
}
groupedProperties[property.group].push(property);
});
看起来该值实际上是一个具有数组属性的对象。换句话说,是数组。state.data.properties
properties
properties.properties
更新 to access 数组rootReducer
data.properties
const initialState = {
properties: data.properties,
};
或将整个对象引用作为值传递。data
initialState
const initialState = data;
例:
import { UPDATE_PROPERTY } from "./actions";
import data from "./data.json";
const initialState = {
properties: data.properties,
};
// Or
// const initialState = data;
const rootReducer = (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case UPDATE_PROPERTY:
return {
...state,
properties: state.properties.map((prop) =>
prop.name === payload.name ? payload : prop
)
};
default:
return state;
}
};
export default rootReducer;
评论
import data from "./data.json";
- 这里的价值是什么?它似乎不是您和代码假设的数组。请编辑以澄清并制作更完整的最小可重复示例。data