商店更改时更新组件

时间:2019-01-03 16:54:51

标签: javascript reactjs redux react-redux

我正在尝试根据商店更新来更新组件,其目的是,当我单击表格项时,我想更新表单按钮以编辑表格并编辑表格项。

enter image description here

enter image description here

我的源代码:

我有一个更新currentUser的操作。 currentUser是我要更新的用户

src / actions / user.js

export const updateCurrentUserSuccess = (currentUser) => {
    return {
        type: UPDATE_CURRENT_USER,
        currentUser
    }
}

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

我的currentUserReducer: src / reducers / currentUserReducer.js

import { UPDATE_CURRENT_USER } from '../constants/ActionTypes';

const initialState = {
    currentUser: [],
}

export default function userReducer(state = initialState, action) {
    switch (action.type) {
        case UPDATE_CURRENT_USER:
            return action.currentUser;
        default: 
            return state;
    }
}

现在是我的组件:

我的NewUser表单: src / components / NewUser.js

    import React, { Component } from 'react';
    import { Store } from '../store'

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

        componentDidMount(){
            this.handleUserChange()
        }

        handleInputChange = e => {
            this.handleUserChange();
            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.state.id !== '') {
                    this.props.onEdit(this.state);
                    this.handleReset();
                }
            }

        };

        handleReset = () => {
            Store.getState().currentUser = []
            this.setState({
                id: '',
                name: '',
                cpfcnpj: '',
                isEdit: false
            });
        };

        handleUserChange() {
            console.log('store', Store.getState().currentUser._id);
            if (Store.getState().currentUser._id !== undefined) {
                this.setState({
                    id: Store.getState().currentUser._id,
                    name: Store.getState().currentUser.name,
                    cpfcnpj: Store.getState().currentUser.cpfcnpj,
                    isEdit: true
                });
            }
        }

        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;

my component User item:
***src/components/User.js***

import React from 'react';

export default ({ user: { name, cpfcnpj, _id }, onDelete, onEditUser }) => {
    return (
        <tr>
            <th scope="row">{name}</th>
            <td>{cpfcnpj}</td>
            <td>
                <button className="btn btn-warning btn-xs margin-right" type="button" onClick={() => onEditUser(_id)}>
                    <span className="glyphicon glyphicon-edit" aria-hidden="true"> </span>
                    &nbsp;
                    Editar
                </button>
                <button className="btn btn-danger btn-xs margin-right" type="button" onClick={() => onDelete(_id)}>
                    <span className="glyphicon glyphicon-trash" aria-hidden="true"> </span>
                    &nbsp;
                    Excluir
                </button>
            </td>
        </tr>
    );
};

现在是我的智能组件:

src / containers / UserList.js

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);

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));
        },
        onEdit: (id, name, cpfcnpj) => {
            dispatch(updateUser(id, name, cpfcnpj))
        }
    };
};

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

enter image description here

src / App.js

import React, { Component } from 'react';
import CreateUser from './containers/CreateUser';
import UserList from './containers/UserList';
import './css/main.css'

class App extends Component {
  render() {
    return (
      <div className="container">
        <h1 className="styles-app">Usuários</h1>
        <div className="row styles-app">
          <div className="col-md-12">
            <CreateUser />
          </div>
          <div className="col-md-12">
            <UserList />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

1 个答案:

答案 0 :(得分:1)

您可以尝试以下方法。将您的NewUser.js连接到商店。

import { connect } from 'react-redux;
export default connect(mapStateToProps)(NewUser);

然后将您当前的用户状态映射到道具。

const mapStateToProps = state => {
return {
    currentUser: state.currentUser
  };
};

在您的currentUserReducer

initialState = {
  //Assuming these are the only values in response
  id: '',
  name: '',
  cpfcnpj: '',
  isEdit: false
};

export default function userReducer(state = initialState, action) {
switch (action.type) {
    case UPDATE_CURRENT_USER:
        return {
          ...state,
          id: action.currentUser.id,
          name: action.currentUser.name,
          cpfcnpj: action.currentUser.cpfcnpj,
          isEdit: true
        };
    default: 
        return state;
  }
}

您现在应该可以在props中访问当前用户对象。

然后在您的输入值字段中

value={this.props.currentUser.name}
value={this.props.currentUser.cpfcnpj}

您可能还需要检查这些值是否已更新。另外,不确定placeholder文本是否会干扰。

希望这使您更接近解决方案。

修改

在清理道具的情况下,您可以添加其他操作来这样做。 在针对currentUser的操作中:

export const clearUserData = () => {
return {
    type: CLEAR_USER_DATA,
  }
}

在减速器中:

export default function userReducer(state = initialState, action) {
switch (action.type) {
case UPDATE_CURRENT_USER:
    return {
      ...state,
      id: action.currentUser.id,
      name: action.currentUser.name,
      cpfcnpj: action.currentUser.cpfcnpj,
      isEdit: true
    };
case CLEAR_USER_DATA:
  return {
      ...state,
      id: '',
      name: '',
      cpfcnpj: '',
      isEdit: false
    };
default: 
    return state;
 }
}

添加clearUserData操作以在提交编辑后执行,它应该重置您的reducer。您甚至可以做到

return {
  ...state,
  initialState
};