简体   繁体   English

当商店改变时更新组件

[英]Update component when the store changes

I'm trying to update a component based on store updates, the objective of that is, when I click on a table item, I want to update the form buttons to edit form, and Edit the table item.我正在尝试根据商店更新更新组件,目的是当我单击表项时,我想更新表单按钮以编辑表单,并编辑表项。

在此处输入图片说明

在此处输入图片说明

My source code:我的源代码:

I have an action which updates currentUser .我有一个更新currentUser的操作。 currentUser is the user I want to update currentUser是我要更新的用户

src/actions/user.js源代码/操作/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);
            });
    };
};

my currentUserReducer: src/reducers/currentUserReducer.js我的 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;
    }
}

now my components:现在我的组件:

my NewUser form: src/components/NewUser.js我的 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>
    );
};

now my smart components:现在我的智能组件:

src/containers/UserList.js src/容器/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 src/容器/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);

在此处输入图片说明

src/App.js源代码/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;

Here is something you might try.这是您可以尝试的方法。 Connect your NewUser.js to the store.将您的NewUser.js连接到商店。

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

Then map your currentUser state to props.然后将您的 currentUser 状态映射到 props。

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

In your currentUserReducer在您的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;
  }
}

You should have access to the current user object now in props.您现在应该可以访问 props 中的当前用户对象。

Then in your input value field然后在您的输入值字段中

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

You may also need to do a check to see if these values have been updated.您可能还需要检查这些值是否已更新。 Also, not sure if the placeholder text might interfere.另外,不确定placeholder文本是否会干扰。

Hope this gets you closer to the solution.希望这能让您更接近解决方案。

Edit编辑

In the case of clearing props, you might just add another action to do so.在清除道具的情况下,您可能只需添加另一个操作即可。 In your actions for currentUser:在您对 currentUser 的操作中:

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

And in your reducer:在你的减速机中:

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

Add the clearUserData action to execute after you submit your edits and it should reset your reducer.添加要在提交编辑后执行的 clearUserData 操作,它应该重置您的减速器。 You might even be able to just do你甚至可以做

return {
  ...state,
  initialState
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM