admin管理员组

文章数量:1399013

I have two reactJS ponents:

  1. CustomerForm ponent with a form and form handling code.
  2. CustomerList ponent which lists the customers using react-table.

Both ponents are functional and I can use the form to add data to the database, and then fetch and display data in react-table.

But I can't figure out how to refresh the react-table data on successful form submission.

I am loading the ponents directly into an HTML page and using babel to process JSX. I am just starting our with reactJS and more used to PHP/jQuery development, so maybe I am approaching this wrong. Would appreciate any feedback.

My code:

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

Customer List

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

I have two reactJS ponents:

  1. CustomerForm ponent with a form and form handling code.
  2. CustomerList ponent which lists the customers using react-table.

Both ponents are functional and I can use the form to add data to the database, and then fetch and display data in react-table.

But I can't figure out how to refresh the react-table data on successful form submission.

I am loading the ponents directly into an HTML page and using babel to process JSX. I am just starting our with reactJS and more used to PHP/jQuery development, so maybe I am approaching this wrong. Would appreciate any feedback.

My code:

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

Customer List

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);
Share Improve this question edited May 28, 2019 at 14:14 Sujal Patel 2,5422 gold badges21 silver badges40 bronze badges asked May 28, 2019 at 13:12 Jatinder ThindJatinder Thind 2122 gold badges3 silver badges12 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

TL;DR

Render both ponents in a parent ponent. Lift the table state up and pass a function to the form that will call the function to fetch data.


First of all, one quick tip. Render only one ponent in one div and then nest all the other ponents inside.

In both files, you are rendering the ponent in diferent selectors

CustomerForm

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

Customer List

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

This isn't good because this way, it's not easy to share state and props between then.

What you should do is have a root ponent that render both ponents.

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

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

OBSERVATION I'm not sure what is the e function and why you are using, but I assume this won't change anything, but please, specify what it is.

Doing this, you can share state and props between ponents.

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

Here what I'm doing is called Lifting State Up. I'm getting the state of CustomerList to the parent ponent so you can reload the data when the form calls reloadData.

This way you also need to change CustomerList to get the data from this.props and in CustomerForm call reloadData when the submit is success.

Customer List

  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

Call this.props.reloadData() when the submit is success.

*I don't know when you want to reload the data, it's not clear when is a succes.

本文标签: javascriptHow to reloadrefresh a reacttable component from my form componentStack Overflow