【问题标题】:React Redux: How to create state objects based on data that will change and how to update individual elements within each objectReact Redux:如何根据将要更改的数据创建状态对象以及如何更新每个对象中的单个元素
【发布时间】: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


    【解决方案1】:

    已解决 - 转换为对象,在名称中使用多个值然后拆分为数组。

    【讨论】:

      猜你喜欢
      • 2021-06-14
      • 1970-01-01
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 2021-03-27
      • 1970-01-01
      相关资源
      最近更新 更多