【问题标题】:How to reload/refresh a react-table component from my form component如何从我的表单组件重新加载/刷新反应表组件
【发布时间】:2019-10-14 00:48:41
【问题描述】:

我有两个 reactJS 组件:

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

这两个组件都是功能性的,我可以使用表单将数据添加到数据库中,然后在 react-table 中获取和显示数据。

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

我将组件直接加载到 HTML 页面中并使用 babel 来处理 JSX。我刚刚开始使用 reactJS 并且更习惯于 PHP/jQuery 开发,所以也许我正在接近这个错误。如有任何反馈,将不胜感激。

我的代码:

客户表单

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

【问题讨论】:

    标签: javascript reactjs react-table


    【解决方案1】:

    TL;DR

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


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

    在这两个文件中,您都在不同的选择器中渲染组件

    客户表单

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

    客户列表

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

    这不好,因为这样在它们之间共享 state 和 props 并不容易。

    你应该做的是有一个渲染两个组件的根组件。

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

    客户表单

    提交成功后调用this.props.reloadData()

    *不知道什么时候要重新加载数据,不清楚什么时候成功。

    【讨论】:

      猜你喜欢
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 2019-03-03
      • 1970-01-01
      • 2013-01-13
      • 2021-12-10
      • 1970-01-01
      相关资源
      最近更新 更多