【发布时间】:2020-08-19 11:13:41
【问题描述】:
问题:我不知道如何组织我的状态以轻松对其进行更改。它作为对象数组检索。它被映射到组件中,但对单个元素进行更新,然后找出如何在数据库中更新这些元素。
应用设置:React Redux Saga Node Express Postgres
fetch 调用检索对象数组(用户详细信息),将其添加到状态对象,然后该数组用于映射具有 4 个输入的组件。我希望能够更改任何对象的任何元素并将其更新为状态。然后我会添加一个 fetch 来更新对数据库的原始数据的任何更改。我正在寻找有助于奠定基础的信息,例如网站、书籍、课程等,以便我可以解决这个问题。
以下是我的代码部分供参考;
数据
userData: Array(4)
0: {firstname: "shane", surname: "smith", email: "shanesmith@gmail.com", auth: false}
1: {firstname: "Sahne", surname: "Smith", email: "shane@gmail.com", auth: false}
etc....
减速器
FETCH_ADMIN_PAGE_START,
FETCH_ADMIN_PAGE_SUCCESS,
FETCH_ADMIN_PAGE_FAILURE,
UPDATE_ADMIN_USER_DATA,
} from "../types/types";
// import utility functions
const INITIAL_STATE = {
isFetching: false,
userData: [],
errorMessage: null,
};
const adminReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case FETCH_ADMIN_PAGE_START:
return {
...state,
isFetching: true,
};
case FETCH_ADMIN_PAGE_SUCCESS:
return {
...state,
isFetching: false,
userData: action.payload.user[0],
};
case FETCH_ADMIN_PAGE_FAILURE:
return {
...state,
errorMessage: action.payload,
};
case UPDATE_ADMIN_USER_DATA:
return {
...state,
userData: [haven't found a silution],
};
default:
return state;
}
};
export default adminReducer;
动作
import {
FETCH_ADMIN_PAGE_START,
FETCH_ADMIN_PAGE_SUCCESS,
FETCH_ADMIN_PAGE_FAILURE,
UPDATE_ADMIN_USER_DATA,
} from "../types/types";
export const fetchAdminPageStart = () => ({
type: FETCH_ADMIN_PAGE_START,
});
export const fetchAdminPageSuccess = (data) => ({
type: FETCH_ADMIN_PAGE_SUCCESS,
payload: data,
});
export const fetchAdminPageFailure = (errorMessage) => ({
type: FETCH_ADMIN_PAGE_FAILURE,
payload: errorMessage,
});
export const updataAdminUserData = (data) => ({
type: UPDATE_ADMIN_USER_DATA,
payload: data,
});
组件
import * as React from "react";
import { useState, useEffect } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import PropTypes from "prop-types";
// Material Ui Componnents
import AppBar from "@material-ui/core/AppBar";
import Tab from "@material-ui/core/Tab";
//Components
import UserDetailsComponent from "../../components/container-withheader/users-details.component";
// Styled Components
import { StyledTabs } from "./admin-page.styles";
// Selectors
import { selectAdminPageUserData } from "../../redux/admin-page/admin-page.selectors";
// Actions
import { updataAdminUserData } from "../../redux/admin-page/admin-page.actions";
const AdminPageComponent = ({ userDetails, updataAdminUserData }) => {
useEffect(() => {}, []);
// const [userData, setUserData] = useState({ users: userDetailData });
const [selectedTab, setSelectedTab] = useState(0);
const handleTabChange = (event, newValue) => {
setSelectedTab(newValue);
};
const handleChangeData = (event) => {
console.log(event.target.name);
return updataAdminUserData(event.target);
};
const handleToggleChange = (event) => {
console.log(event.target);
return updataAdminUserData(event.target);
};
const tabArray = ["Users", "Options"];
return (
<div>
<AppBar position='static' color='default'>
<StyledTabs
value={selectedTab}
onChange={handleTabChange}
variant='scrollable'
scrollButtons='auto'
aria-label='scrollable auto tabs example'
>
{tabArray.map((tab, i) => (
<Tab label={tab} key={i} />
))}
</StyledTabs>
</AppBar>
{selectedTab === 0 && (
<UserDetailsComponent
userData={userDetails}
handleChangeData={handleChangeData}
handleToggleChange={handleToggleChange}
/>
)}
</div>
);
};
AdminPageComponent.propTypes = {
userDetails: PropTypes.object,
updataAdminUserData: PropTypes.func,
};
const mapStateToProps = createStructuredSelector({
userDetails: selectAdminPageUserData,
});
const mapDispatchToProps = (dispatch) => ({
updataAdminUserData: (data) => dispatch(updataAdminUserData(data)),
});
export default connect(mapStateToProps, mapDispatchToProps)(AdminPageComponent);
上面的子组件
import React, { useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Paper from "@material-ui/core/Paper";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Switch from "@material-ui/core/Switch";
import PropTypes from "prop-types";
// Styled Components
import {
StyledToolBar,
GridContainer,
RightElement,
StyledTextField,
StyledSwitch,
} from "./users-details.styles";
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
}));
const UserDetailsComponent = ({
userData,
handleChangeData,
handleToggleChange,
}) => {
const classes = useStyles();
const [edit, setEdit] = useState({
editUser: true,
});
const handleEditChange = (event) => {
setEdit({ ...edit, [event.target.name]: event.target.checked });
};
return (
<div className={classes.root}>
<br></br>
<StyledToolBar elevation={3}>
<GridContainer>
<RightElement>
<FormControlLabel
control={
<Switch
checked={edit.editUser}
onChange={handleEditChange}
name='editUser'
/>
}
label='Edit User'
/>
</RightElement>
</GridContainer>
</StyledToolBar>
<br></br>
<Paper styles={{ paddingTop: "2rem" }} elevation={3}>
<form className={classes.root} noValidate autoComplete='on'>
{userData.map((user, i) => (
<div key={i}>
<StyledTextField
name={Number(i)}
title={"Enter first name here"}
alt={"firstname"}
id={`firstname`}
input={`firstname`}
onChange={handleChangeData}
disabled={edit.editUser}
label='First Name'
value={user.firstname}
variant='outlined'
/>
<StyledTextField
name={Number(i)}
id={"surname"}
disabled={edit.editUser}
label='Surame'
value={user.surname}
variant='outlined'
/>
<StyledTextField
name={Number(i)}
id={"email"}
disabled={edit.editUser}
label='Email'
value={user.email}
variant='outlined'
/>
<React.Fragment>
<FormControlLabel
control={
<StyledSwitch
disabled={edit.editUser}
checked={user.auth}
onChange={handleToggleChange}
name={Number(i)}
id={"auth"}
/>
}
label='Has Administration Access'
/>
</React.Fragment>
</div>
))}
</form>
</Paper>
</div>
);
};
export default UserDetailsComponent;
如您所见,我还需要找到一种更好的方式在事件中传递信息,以区分我希望修改的每个状态。
我不知道是否应该将数组修改为另一种类型的对象,如果这样做,我该如何映射用户。解决此问题的最佳做法是什么。
最终,我只是想学习或被指出可以帮助我解决这个问题的信息方向。非常感谢任何帮助。
提前谢谢你。
【问题讨论】:
标签: reactjs postgresql redux state manpage