如何从表单组件重新加载/刷新反应表组件

时间:2019-05-28 13:12:38

标签: javascript reactjs react-table

我有两个reactJS组件:

  1. 具有表单和表单处理代码的CustomerForm组件。
  2. CustomerList组件,该组件使用react-table列出客户。

这两个组件都起作用,我可以使用该表单将数据添加到数据库中,然后在react-table中获取并显示数据。

但是我不知道如何在成功提交表单后刷新反应表数据。

我将组件直接加载到HTML页面中,并使用babel处理JSX。我只是从reactJS开始,更多地用于PHP / jQuery开发,所以也许我正在解决这个错误。希望得到您的反馈。

我的代码:

CustomerForm

class CustomerForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {data: [], name: '', phone: '', nameErr: '', phoneErr: ''};
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        const target = event.target;
        const name = target.name;
        this.setState({[name]: event.target.value});
    }

    handleSubmit(event) {
        event.preventDefault();

        var self = this;

        axios.post(APP_URL + '/customer/add', {
            name: this.state.name,
            phone: this.state.phone
        }).then(function (response) {
            //console.log(response);
            var data = response.data;
            if (data.status === 0) {
                if (typeof data.payload === 'object') {
                    for (var key in data.payload) {
                        if (data.payload[key]) {
                            self.setState({[key]: data.payload[key]});
                        }
                    }
                }
            }
        }).catch(function (error) {
            console.log(error);
        });
    }

    render() {
        return (
                <div className="container mt-3">
                    <form onSubmit={this.handleSubmit}>
                        <div className="row">
                            <div className="col-6">
                                <div className="form-group">
                                    <label>Name</label>
                                    <input name="name" type="text" className={'form-control ' + (this.state.nameErr ? 'is-invalid' : '')} placeholder="Enter name"  value={this.state.value} onChange={this.handleChange} />
                                    <div className="invalid-feedback">{this.state.nameErr}</div>
                                </div>
                                <div className="form-group">
                                    <label>Email address</label>
                                    <input name="phone" type="text" className="form-control" placeholder="Enter phone"  value={this.state.value} onChange={this.handleChange} />
                                </div>
                                <button type="submit" className="btn btn-primary">Submit</button>
                            </div>
                        </div>
                    </form>
                </div>

                );
    }
}

const domContainer = document.querySelector('#CustomerFormContainer');
ReactDOM.render(e(CustomerForm), domContainer);

客户列表

class CustomerList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {data: [], loading: false, pages: null};
        this.fetchData = this.fetchData.bind(this);
    }

    fetchData(state, instance) {
        var self = this;

        this.setState({loading: true});

        axios.post(APP_URL + '/customer/index', {
            page: state.page,
            pageSize: state.pageSize,
            sorted: state.sorted,
            filtered: state.filtered
        }).then(function (response) {
            // handle success
            self.setState({
                data: response.data.payload,
                pages: 1,
                loading: false
            });
        }).catch(function (error) {
            // handle error
            console.log(error);
        }).finally(function () {
            // always executed
        });
    }

    render() {
        const {data, pages, loading} = this.state;
        return (
                <div className="container mt-3">
                    <ReactTable
                        columns={[
                                    {
                                        Header: "Name",
                                        accessor: "name"
                                    },
                                    {
                                        Header: "Phone",
                                        accessor: "phone"
                                    }
                                ]}
                        manual
                        data={this.state.data}
                        pages={this.state.pages} 
                        loading={this.state.loading} 
                        onFetchData={this.fetchData} 
                        defaultPageSize={10}
                        className="-striped -highlight"
                        />
                    <br />
                </div>
                );
    }
}

const domContainer = document.querySelector('#CustomerListContainer');
ReactDOM.render(e(CustomerList), domContainer);

1 个答案:

答案 0 :(得分:1)

TL; DR

在父组件中渲染两个组件。 Lift the table state up,然后将一个函数传递给表单,该表单将调用该函数以获取数据。


首先,一个快速提示。在一个div中仅渲染一个组件,然后将所有其他组件嵌套在其中。

在两个文件中,您正在使用不同的选择器渲染组件

CustomerForm

const domContainer = document.querySelector('#CustomerFormContainer');
ReactDOM.render(e(CustomerForm), domContainer);

客户列表

const domContainer = document.querySelector('#CustomerListContainer');
ReactDOM.render(e(CustomerList), domContainer);

这不好,因为这样一来,在此之间共享状态和道具并不容易。

您应该做的是拥有一个同时呈现两个组件的根组件。

class App extends React.Component {
    render() {
        return (
            <CustomerForm />
            <CustomerList />
        )
    }
}

const domContainer = document.querySelector('#app');
ReactDOM.render(e(App), domContainer);

观察 我不确定e函数是什么以及为什么使用它,但是我认为这不会改变任何东西,但是请指定它是什么。

这样做,您可以在组件之间共享状态和道具。

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: [], loading: false, pages: null };
    this.fetchData = this.fetchData.bind(this);
    this.reloadData = this.reloadData.bind(this);
  }

  reloadData() {
    this.fetchData(state);
  }

  fetchData(state, instance) {
    var self = this;

    this.setState({ loading: true });

    axios
      .post(APP_URL + "/customer/index", {
        page: state.page,
        pageSize: state.pageSize,
        sorted: state.sorted,
        filtered: state.filtered
      })
      .then(function(response) {
        // handle success
        self.setState({
          data: response.data.payload,
          pages: 1,
          loading: false
        });
      })
      .catch(function(error) {
        // handle error
        console.log(error);
      })
      .finally(function() {
        // always executed
      });
  }
  render() {
    return (
      <div>
        <CustomerForm reloadData={reloadData} />
        <CustomerList data={data} pages={pages} loading={loading} fetchData={fetchData} />
      </div>
    );
  }
}

这就是我在做的Lifting State Up。我正在将CustomerList的状态传递给父组件,以便在表单调用reloadData时可以重新加载数据。

这样,您还需要更改CustomerList来从this.props获取数据,并在CustomerForm调用reloadData时提交成功。

客户列表

  render() {                                   // getting from props
    const { data, pages, loading, fetchData } = this.props;
    return (
      <div className="container mt-3">
        <ReactTable
          columns={[
            {
              Header: "Name",
              accessor: "name"
            },
            {
              Header: "Phone",
              accessor: "phone"
            }
          ]}
          manual
          data={data}
          pages={pages}
          loading={loading}
          onFetchData={fetchData}
          defaultPageSize={10}
          className="-striped -highlight"
        />
        <br />
      </div>
    );
  }

CustomerForm

提交成功后,致电this.props.reloadData()

*我不知道何时要重新加载数据,不清楚何时成功。