ReactJS检查数据库是否有更改并更新组件而不刷新浏览器

时间:2018-03-14 22:20:04

标签: javascript reactjs

在编辑函数运行并且数据库更新成功后,我无法弄清楚如何使用数据库中的新数据更新组件。

我尝试过this.forceUpdate(),但这并不奏效。我听说过使用this.setState(),但我不知道如何使用数据库更新它,因为我的教室状态是JSON数组。

我一直在思考并且坚持不懈地坚持几天没有运气,所以对此问题的任何建议或帮助将不胜感激。

P.S。我正在使用MySQL作为我的数据库。我不知道这是否重要。

App.js

import React, { Component } from 'react';
import './App.css';

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      toggle: false,
      toggleIdxArray: [],
      classroom: [],
      childflagged: '',
      flagreason: '',
      id: ''
    };
    this.eventHandler = this.eventHandler.bind(this);
    this.logChange = this.logChange.bind(this);
    this.handleEdit = this.handleEdit.bind(this);
  }

  logChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

  handleEdit(event) {
    event.preventDefault()
    var data = {
      childflagged: this.state.childflagged,
      flagreason: this.state.flagreason,
      id: this.state.id
    }
    fetch("/classroom/edit", {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    }).then(function(response) {
      if (response.status >= 400) {
        throw new Error("Bad response from server");
      }
      return response.json();
    }).then(function(data) {
      if (data.affectedRows === 1) {
        console.log('Edited Flag!'); //UPDATE COMPONENT FUNCTION OF SOME-SORT HERE
      }
    }).catch(function(err) {
      console.log(err)
    });

  }

  eventHandler(event, idx) {
    let updatedArr = this.state.toggleIdxArray.slice();
    let checkIdx = updatedArr.indexOf(idx);
    if (checkIdx === -1) updatedArr.push(idx);
    else updatedArr.splice(checkIdx, 1);
    this.setState((prevState) => ({
        toggleIdxArray: updatedArr
      })
    );
  }

  componentDidMount() {
    fetch("/classroom")
    .then(res => res.json())
    .then(classroom => this.setState({ classroom }))
  }

  render() {
    return (
      <div className="App">
                <div className="wrapper">
                    <h1>Classroom</h1>
                    {this.state.classroom.map((classroom, idx) =>
                        <div className="child" key={classroom.id}>
              <p className="detail">Child's Name: <span className={classroom.childflagged}>{classroom.childsname}</span> <i title={classroom.flagreason} className={'fa fa-flag flag' + classroom.childflagged}></i><i title={classroom.starreason} className={'fa fa-star star' + classroom.starstudent}></i></p>
              <p className="detail">Parent's Phone Number: {classroom.parentsnumber}</p>
              <div className="actionMenu">
                <button className="flags" id={classroom.id} onClick={e => this.eventHandler(e, idx)}>Edit Flags</button>
                <button className="results">View Results</button>
                <button className="profile">View Profile</button>
              </div>
              <div className="actionForm">
                <div>
                  <form id={"flagform" + classroom.id} className={this.state.toggleIdxArray.includes(idx) ? '' : 'hide'} onSubmit={this.handleEdit} method="post" autoComplete="no">
                    <input type="hidden" name="id" value={classroom.id} />
                    <input type="text" onChange={this.logChange} value={this.state.childflagged} name="childflagged" placeholder="Flag Type" />
                    <input type="text" onChange={this.logChange} value={this.state.flagreason} name="flagreason" placeholder="Reason For Flag" />
                    <input type="submit" onClick={() => this.state.id = classroom.id} name="submit" value="Save Changes" />
                  </form>
                </div>
              </div>
            </div>
          )}
                </div>
      </div>
    );
  }
}

export default App;

3 个答案:

答案 0 :(得分:2)

我使用以下方法解决了这个问题:

}.then((data) => { console.log('Update Complete'); this.setState({ classroom: data }) })

答案 1 :(得分:1)

在请求完成并返回数据后,您可以通过调用setState函数中的handleEdit来触发组件重新渲染:

handleEdit(event) {
    ....
    fetch("/classroom/edit", {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    }).then(function(response) {
      if (response.status >= 400) {
        throw new Error("Bad response from server");
      }
      return response.json();
    }).then(function(data) {
      if (data.affectedRows === 1) {
        /** Calling setState here
         * For example, if the data return is a classroom object,
         * you can update the classroom property of the state to 
         * reflect it
         */
        this.setState({classroom:[...this.state.classroom, data.classroom]});
      }
    })
    ....
  }

基本上,如果出现以下情况,反应组件将重新渲染:

  1. 它的道具改变了。
  2. 它的setState函数叫。
  3. 它的forceUpdate函数叫。
  4. 有关此主题的更多详细信息,请访问:https://reactjs.org/docs/state-and-lifecycle.html

答案 2 :(得分:1)

如果在数据库上更新后以有用的格式取回数据,只需将setState与该数据一起使用:

handleEdit(event) {
    event.preventDefault()
    var data = {
      childflagged: this.state.childflagged,
      flagreason: this.state.flagreason,
      id: this.state.id
    }
    fetch("/classroom/edit", {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    }).then(function(response) {
      if (response.status >= 400) {
        //Aside: because of the way promises work, this is the correct way to throw the error. Doing this you can catch it in the "catch" callback
        Promise.reject(new Error("Bad response from server"));
      }
      return response.json();
    }).then((data) => {
      if (data.affectedRows === 1) {
        console.log('Edited Flag!'); //UPDATE COMPONENT FUNCTION OF SOME-SORT HERE
        //use data to set state
        this.setState({ classroom: data });
      }
    }).catch(function(err) {
      console.log(err)
    });

  }