使用 react redux 编辑表值

Posted

技术标签:

【中文标题】使用 react redux 编辑表值【英文标题】:Edit table values using react redux 【发布时间】:2019-05-29 14:36:42 【问题描述】:

我正在学习 React-Redux 并且我陷入了学习的一部分,我正在尝试使用已经存在的表单从表中编辑用户值,从而获取该行的值并传递给表单,并将用户 ID 保存在变量或类型中以更新用户,我不知道如何继续该部分

我的操作:src/actions/user.js

import  ADD_USER, DELETE_USER, UPDATE_USER, FETCH_USER  from '../constants/ActionTypes';
import axios from 'axios';

const apiUrl = 'http://localhost:8080/api/v1';

export const createUser = ( name, cpfcnpj ) => 
    return (dispatch) => 
        return axios.post(`$apiUrl/users/`,  name, cpfcnpj )
            .then(response => 
                dispatch(createUserSuccess(response.data.data))
            )
            .catch(error => 
                throw (error);
            );
    ;
;

export const createUserSuccess = (data) => 
    return 
        type: ADD_USER,
        payload: 
            _id: data._id,
            name: data.name,
            cpfcnpj: data.cpfcnpj
        
    
;

export const deleteUserSuccess = id => 
    return 
        type: DELETE_USER,
        payload: 
            id
        
    


export const deleteUser = (id) => 
    console.log(id)
    return (dispatch) => 
        return axios.delete(`$apiUrl/users/$id`)
            .then(response => 
                dispatch(deleteUserSuccess(id))
            )
            .catch(error => 
                throw (error);
            );
    ;
;

export const updateUserSuccess = (data) => 
    return 
        type: UPDATE_USER,
        payload: 
            _id: data._id,
            name: data.name,
            cpfcnpj: data.cpfcnpj
        
    


export const updateUser = (id, name, cpfcnpj) => 
    console.log(id, name, cpfcnpj)
    return (dispatch) => 
        return axios.put(`$apiUrl/users/$id`,  name, cpfcnpj )
            .then(response => 
                dispatch(updateUserSuccess(response.data.data))
            )
            .catch(error => 
                throw (error);
            );
    ;
;

export const fetchUsers = (users) => 
    return 
        type: FETCH_USER,
        users
    
;

export const fetchAllUsers = () => 
    return (dispatch) => 
        return axios.get(`$apiUrl/users/`)
            .then(response => 
                dispatch(fetchUsers(response.data.data))
            )
            .catch(error => 
                throw (error);
            );
    ;
;

我的智能组件 CreateUser:src/containers/CreateUser.js

import  connect  from 'react-redux';
import  createUser, updateUser  from '../actions/user';
import NewUser from '../components/NewUser';

const mapDispatchToProps = dispatch => 
    return 
        onAddUser: user => 
            dispatch(createUser(user));
        
    ;
;

export default connect(
    null,
    mapDispatchToProps
)(NewUser);

我的虚拟组件 NewUser:src/components/NewUser.js

import React,  Component  from 'react';

class NewUser extends Component 
    state = 
        name: '',
        cpfcnpj: '',
        isEdit: false
    ;

    handleInputChange = e => 
        this.setState(
            [e.target.name]: e.target.value
        );
    ;

    handleSubmit = e => 
        e.preventDefault();
        if (!this.state.isEdit) 
            if (this.state.name.trim() && this.state.cpfcnpj.trim()) 
                this.props.onAddUser(this.state);
                this.handleReset();
            
         else 
            if (this.state.name.trim() && this.state.cpfcnpj.trim()) 
                this.props.onEdit(this.state);
                this.handleReset();
            
        

    ;

    handleReset = () => 
        this.setState(
            name: '',
            cpfcnpj: ''
        );
    ;

    render() 
        return (
            <div>
                <form className="form-inline" onSubmit=this.handleSubmit>
                    <div className="form-group margin-right">
                        <input
                            type="text"
                            placeholder="Name"
                            className="form-control"
                            name="name"
                            onChange=this.handleInputChange
                            value=this.state.name
                        />
                    </div>
                    <div className="form-group margin-right">
                        <input
                            type="text"
                            placeholder="CPF/CNPJ"
                            className="form-control"
                            name="cpfcnpj"
                            onChange=this.handleInputChange
                            value=this.state.cpfcnpj>
                        </input>
                    </div>
                    <div className="form-group">
                        <button type="submit" className=this.state.isEdit ? "btn btn-success margin-right hidden" : "btn btn-success margin-right">
                            <span className="glyphicon glyphicon-plus" aria-hidden="true"></span>
                            &nbsp;
                            Adicionar
                        </button>
                        <button type="submit" className=this.state.isEdit ? "btn btn-primary margin-right" : "btn btn-primary margin-right hidden">
                            <span className="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
                            &nbsp;
                            Salvar
                        </button>
                        <button type="button" className="btn btn-default margin-right" onClick=this.handleReset>
                            <span className="glyphicon glyphicon-erase" aria-hidden="true"></span>
                            &nbsp;
                            Limpar
                        </button>
                    </div>
                </form>
            </div>
        );
    


export default NewUser;

src/containers/UserList.js

import React from 'react';
import  connect  from 'react-redux';
import User from '../components/User';
import  deleteUser, updateUser  from '../actions/user';

function UserList( users, onDelete, onEdit ) 
    if (!users.length) 
        return (
            <div className="margin-top">
                No Users
            </div>
        )
    
    return (
        <div className="margin-top">
            <table className="table table-striped">
                <thead>
                    <tr>
                        <th scope="col">Nome</th>
                        <th scope="col">CPF/CNPJ</th>
                    </tr>
                </thead>
                <tbody>
                    users.map(user => 
                        return (
                            <User user=user onDelete=onDelete key=user._id onEdit=onEdit />
                        );
                    )
                </tbody>
            </table>
        </div>
    );


const mapStateToProps = state => 
    return 
        users: state.users
    ;
;

const mapDispatchToProps = dispatch => 
    return 
        onDelete: id => 
            dispatch(deleteUser(id));
        ,
        onEdit: id => 
            dispatch(updateUser(id))
        
    ;
;

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(UserList);

src/reducers/userReducer.js

import  ADD_USER, DELETE_USER, UPDATE_USER, FETCH_USER  from '../constants/ActionTypes';

export default function userReducer(state = [], action) 
    switch (action.type) 
        case ADD_USER:
            return [...state, action.payload];
        case DELETE_USER:
            return state.filter(user => user._id !== action.payload.id);
        case UPDATE_USER:
            return [...state, action.payload];
        case FETCH_USER:
            return action.users;
        default:
            return state;
    

我想到但无法重现的解决方案

我需要获取UserList中作为key来的值表项的id的值,传递给用户组件按钮的onClick参数,在某个表中点击编辑时传递id的值项目添加到 NewUser 中的表单,以便能够在 NewUser 中使用 onEdit 编辑表格项目。


陷入解决方案 ma_dev_15

我用当前用户创建了一个 const initialState,但我的 userReducer State 只是查看用户,

src/recuders/userReducer.js 从 '../constants/ActionTypes' 导入 ADD_USER, DELETE_USER, UPDATE_USER, UPDATE_CURRENT_USER, FETCH_USER ;

const initialState = 
    users: [],
    currentUser: ,


export default function userReducer(state = initialState, action) 
    switch (action.type) 
        case ADD_USER:
            return [...state, action.payload];
        case DELETE_USER:
            return state.filter(user => user._id !== action.payload.id);
        case UPDATE_USER:
            return updateObject(state, action)
        case UPDATE_CURRENT_USER:
            return [...state, action.currentUser];
        case FETCH_USER:
            return action.users;
        default: 
            return state;
    


function updateObject(array, action) 

    return array.map((item, index) => 
        if (item._id !== action.payload._id) 
            return item
        

        return 
            ...item,
            ...action.payload
        
    )

导出减速器 src/reducers/index.js

import  combineReducers  from 'redux';
import users from './userReducer';
import currentUser from './userReducer';

export default combineReducers(
    users: users,
    currentUser: currentUser
);

用户操作:src/actions/user.js

//Ommited
export const updateCurrentUserSuccess = (currentUser) => 
    return 
        type: UPDATE_CURRENT_USER,
        currentUser
    


export const updateCurrentUser = (id) => 
    return (dispatch) => 
        return axios.get(`$apiUrl/users/$id`)
            .then(response => 
                dispatch(updateCurrentUserSuccess(response.data.data))
            )
            .catch(error => 
                throw (error);
            );
    ;
;
//Ommited

我将我的 UserList 连接到 CreateUser

src/components/containers/UserList

import React from 'react';
import  connect  from 'react-redux';
import User from '../components/User';
import  deleteUser, updateCurrentUser  from '../actions/user';
import NewUser from '../components/NewUser';

function UserList( users, onDelete, onEditUser ) 
    if (!users.length) 
        return (
            <div className="margin-top">
                No Users
            </div>
        )
    
    return (
        <div className="margin-top">
            <table className="table table-striped">
                <thead>
                    <tr>
                        <th scope="col">Nome</th>
                        <th scope="col">CPF/CNPJ</th>
                    </tr>
                </thead>
                <tbody>
                    users.map(user => 
                        return (
                            <User user=user onDelete=onDelete onEditUser=onEditUser key=user._id />
                        );
                    )
                </tbody>
            </table>
        </div>
    );


const mapStateToProps = state => 
    return 
        users: state.users
    ;
;

const mapDispatchToProps = dispatch => 
    return 
        onDelete: id => 
            dispatch(deleteUser(id));
        ,
        onEditUser: (id) => 
            dispatch(updateCurrentUser(id))
        
    ;
;

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(UserList, NewUser);

当我单击“编辑”并尝试在 NewUser.js 中查看 console.log(Store.getState) 时,只会返回所有用户,我没有 currentUser。

【问题讨论】:

【参考方案1】:

您可以像这样创建 userReducer 状态:

const initialState = 
  users: [],
  currentUser :,


export default function userReducer(state = initialState, action) 
    switch (action.type) 
        case ADD_USER:
            return [...state, action.payload];
        case DELETE_USER:
            return state.filter(user => user._id !== action.payload.id);
        case UPDATE_USER:
            return [...state, action.payload];
        case FETCH_USER:
            return action.users;
        default:
            return state;
    

然后让我告诉你几个简单的步骤:

    在单击编辑按钮时传递userId 并对应于该操作更新 currentUseruserReducer。 使NewUser组件连接组件并从存储中获取currentUser并设置到输入字段。 成功编辑后,将currentUser 更新为空并更新users 列表

我希望你明白我的意思。如果您卡在某个地方,请告诉我。

【讨论】:

您好,感谢您的回复,我陷入了困境,您知道如何更新 userReducer 中的 currentUser 状态吗?我这样做了,但没有用: const initialState = users: [], currentUser: , export default function userReducer(state = initialState, action) switch (action.type) //Ommitedz case UPDATE_CURRENT_USER:返回 [...state, action.currentUser]; //省略 当我这样做时,返回 [...state, action.currentUser];或 [...state, action.currentUser] 应用程序返回所有用户,而不仅仅是 currentUser 是的,您需要在单击编辑按钮时从组件触发一个操作,然后传递用户 ID 并将用户详细信息复制到 currentUser 并在 NewUser 组件中映射 currentUser 不确定你为什么要结合reducer?

以上是关于使用 react redux 编辑表值的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 React 和 Redux 将相同的表单组件用于添加或编辑模式

使用 React-Router 和 Redux 时单击链接时如何调度操作?

Lerna,React-Redux Web应用程序使用可视代码编辑器调试器调试Chrome插件

React-Redux 设计方法 - 可编辑文本字段双向绑定的 Redux 操作或本地函数

react + redux 应用程序中的 agGrid 正在修改底层数据

React/Redux 中具有默认值的文本输入