【问题标题】:How can I update react app that gets it's data from the node mongo backend using redux如何更新使用 redux 从节点 mongo 后端获取数据的反应应用程序
【发布时间】:2020-06-15 21:05:57
【问题描述】:

您的帮助将不胜感激。我一直在使用 Redux 开发一个 react crud 应用程序。我可以删除、添加甚至从 node express 后端获取信息,但我无法更新应用程序。 我希望能够单击编辑按钮并在编辑页面上获取目标信息,例如 id、描述和其他内容。 这是编辑组件

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { updateIssue, fetchIssue } from '../actions/IssueAction';

class EditIssue extends Component {
  state = {
    description: '',
    severity: '',
    assignedTo: '',
  };

  componentDidMount() {
    const { description, severity, assignedTo } = this.props.Issues;
    this.setState({
      description: description,
      severity: severity,
      assignedTo: assignedTo,
    });
  }

  onChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    });
  };
  onSubmit = (e) => {
    e.preventDefault();

    const post_Issue = {
      description: this.state.description,
      severity: this.state.severity,
      assignedTo: this.state.assignedTo,
    };

    this.props.updateIssue(post_Issue);

    window.location = '/';
  };

  render() {
    return (
      <div>
        <h3>Add New Issue</h3>
        <form onSubmit={this.onSubmit}>
          <div className="form-group">
            <label>Description: </label>
            <input
              type="text"
              name="description"
              className="form-control"
              placeholder="Describe the issue..."
              value={this.state.description}
              onChange={this.onChange}
            />
          </div>

          <div className="form-group">
            <label>Severity</label>
            <select
              name="severity"
              className="form-control"
              value={this.state.severity}
              onChange={this.onChange}
            >
              <option value="Low">Low</option>
              <option value="Medium">Medium</option>
              <option value="High">High</option>
            </select>
          </div>

          <div className="form-group">
            <label>Assigned To: </label>
            <input
              type="text"
              name="assignedTo"
              className="form-control"
              placeholder="Enter Responsible..."
              value={this.state.assignedTo}
              onChange={this.onChange}
            />
          </div>

          <div className="form-group">
            <input
              type="submit"
              value="Update the issue"
              className="btn btn-primary"
            />
          </div>
        </form>
      </div>
    );
  }
}

const mapStateToProps = (state) => ({
  Issues: state.Issues,
});

export default connect(mapStateToProps, { updateIssue, fetchIssue })(EditIssue);

这是更新的动作文件

export const updateIssue = (post_Issue) => (dispatch) => {
  console.log('Edit clicked');
  axios
    .post(`http://localhost:5000/issues/update/${post_Issue._id}`, post_Issue)
    .then((res) =>
      dispatch({
        type: EDIT_ISSUE,
        payload: res.data,
      })
    );
};

这就是减速器

import {
    FETCH_ISSUE,
    POST_ISSUE,
    DELETE_ISSUE,
    EDIT_ISSUE,
    ITEMS_LOADING
} from '../actions/type';

const initialState = {
    Issues: [],
    loading: false
};

export default function (state = initialState, action) {
    switch (action.type) {
        case FETCH_ISSUE:
            return {
                ...state,
                Issues: action.payload,
                    loading: false
            };
        case POST_ISSUE:
            return {
                ...state,
                Issues: [action.payload, ...state.Issues]
            };
        case DELETE_ISSUE:
            return {
                ...state,
                Issues: state.Issues.filter(Issue => Issue._id !== action.payload)
            };
        case EDIT_ISSUE:
            return {
                ...state,
                Issues: [action.payload, ...state.Issues]
            };
        case ITEMS_LOADING:
            return {
                ...state,
                loading: true
            };
        default:
            return state;
    }
}

【问题讨论】:

    标签: node.js reactjs mongodb redux


    【解决方案1】:

    问题在于您的减速器和操作。

    //this will add new element instead updating selected existing one.
        case EDIT_ISSUE:
                    return {
                        ...state,
                        Issues: [action.payload, ...state.Issues]
                    };
    

    如下所示更新 action 和 reducer。

    export const updateIssue = (post_Issue) => (dispatch, getState) => { //add getState
    
      const issues = getState().Issues; // get all issues
    
      axios
        .post(`http://localhost:5000/issues/update/${post_Issue._id}`, post_Issue)
        .then((res) => {
          //update selected issue after api success 
          for (let index = 0; index < issues.length; index++) {
            if (issue._id === post_Issue._id) {
              let selectedIssue = issues[index];
              selectedIssue = { ...selectedIssue, ...post_Issue };
              issues[index] = selectedIssue;
            }
          }
          //dispatch updated issues lists
          dispatch({
            type: EDIT_ISSUE,
            payload: issues,
          })
        }
        );
    };
    

    减速器

    case EDIT_ISSUE:
    return {
      ...state,
      Issues: state.Issues // re-asssign issues
    };
    

    【讨论】:

    • 您好!我已经进行了上述更改,但仍然对 if 语句中 axios 帖子中的 issue._id 来自哪里感到困惑。它显示一个错误,找不到它
    【解决方案2】:

    这可以很简单地完成。

    只需在 componentDidMount 中使用该数据 id 调用 reducer 操作(使用 id 获取是为了在 db 中获取正确的数据 byId )并在节点 js 响应如下后在 componentDidUpdate 中获取更新的道具

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    import { updateIssue, fetchIssue } from '../actions/IssueAction';
    
    class EditIssue extends Component {
      state = {
        description: '',
        severity: '',
        assignedTo: '',
      };
    
      componentDidMount() {
    // you need to figure out a way to have id here ... as a props or state 
    const { id, fetchIssue } = this.props;
     fetchIssue(id)
    
    
      }
    
    componentDidUpdate() {
    if(this.props.Issues.length ){ 
    const { description, severity, assignedTo } = this.props.Issues;
        this.setState({
          description: description,
          severity: severity,
          assignedTo: assignedTo,
        });
    
    }
    
    }
    
      onChange = (e) => {
        this.setState({
          [e.target.name]: e.target.value,
        });
      };
      onSubmit = (e) => {
        e.preventDefault();
    
        const post_Issue = {
          description: this.state.description,
          severity: this.state.severity,
          assignedTo: this.state.assignedTo,
        };
    
        this.props.updateIssue(post_Issue);
    
        window.location = '/';
      };
    
      render() {
    if(!this.props.Issue) return <div> return something else since this is before node js respond </div>;
        return (
          <div>
            <h3>Add New Issue</h3>
            <form onSubmit={this.onSubmit}>
            // your form fields...
            </form>
          </div>
        );
      }
    }
    
    const mapStateToProps = (state) => ({
      Issues: state.Issues,
    });
    
    export default connect(mapStateToProps, { updateIssue, fetchIssue })(EditIssue);
    
    

    不要忘记在节点 js 响应之前渲染一些其他 jsx 元素,就像我上面的示例一样。

    希望对你有帮助!!

    【讨论】:

    • 您好!我已经进行了上述更改,但收到来自 fetchIssue(id) 的错误。我什至不明白它来自哪里。 fetchIssue 是从数据库中获取问题的操作。
    • 您需要在 componentDidMount 中有 id,我编辑了答案以阐明我的意思
    • 好的!做出了改变。现在不应该是 this.props.fetchIssue(id) 而不是 fetchIssue(id)
    • 已应用所有更改。现在我认为问题可能出在行动上
    • 这就是reducer的样子case EDIT_ISSUE: return { ...state, Issues: state.Issues };
    猜你喜欢
    • 2021-09-12
    • 2021-10-06
    • 2020-06-02
    • 1970-01-01
    • 2021-07-26
    • 2019-10-15
    • 2017-12-27
    • 2021-04-25
    • 2021-04-21
    相关资源
    最近更新 更多