【问题标题】:React custom Component(DataTable)反应自定义组件(数据表)
【发布时间】:2020-03-12 11:07:06
【问题描述】:

我是新手,我正在尝试使用参数构建自定义组件。

我只是想知道这样做的确切方法是什么。

这是我当前的代码,我应该如何将这些 Columnsajaxdatasource 传递给组件。 还是我做错了?

import * as React from 'react';
interface Column {
    name: string,
    header: string,
    value: Function
}
export default class DataTable extends React.PureComponent<({
    dataSource: any[],
    ajax: string
    columns: Column[]
    onEdit: Function,
    onDelete: Function
})>{

    public state = {
        dataSource: [],
        ajax: undefined,
        columns: [],
        onEdit: undefined,
        onDelete: undefined
    }

    componentDidMount() {
        if (this.state.ajax != undefined) {
            fetch(this.state.ajax)
                .then(response => response.json())
                .then(data => this.setState({ dataSource: data }));
        }
    }

    render() {

        var template = (
            <table className="table">
                <thead className="thead-darked">
                    {
                        this.state.columns.map((x: Column) => {
                            <th scope="col">{x.header}</th>
                        })
                    }
                </thead>

            </table>)
        return template;
    }
} 

【问题讨论】:

    标签: javascript reactjs typescript asp.net-core react-redux


    【解决方案1】:
    1. 您不需要ajaxcolumnsonEditonDelete 状态。只需使用道具。
    2. this.props.dataSource初始化this.state.dataSource

    以上两项更改将解决您的问题。此外,

    1. 如果ajax 属性发生变化,您可能需要再次获取数据。您必须为该行为实现 componentDidUpdate 方法。但是,我建议制作一个函数组件并使用useEffect 钩子。
    2. 如果dataSource 属性更改,您的dataSource 状态将不会更新。尽管您可以添加更多代码来避免错误,但它可能会导致错误行为。如果将“ajax”部分移到组件外,只使用dataSource prop,逻辑会更清晰,不易出错。

    以下是更新后的代码。

    interface Props {
        dataSource: any[],
        ajax: string,
        columns: Column[],
        onEdit: Function,
        onDelete: Function
    }
    
    export default class DataTable extends React.PureComponent<Props>{
      public state = {
        dataSource: this.props.dataSource,
      }
    
      componentDidMount() {
        if (this.props.ajax != undefined) {
          fetch(this.props.ajax)
            .then(response => response.json())
            .then(data => this.setState({ dataSource: data }));
        }
      }
    
      render() {
        const template = (
          <table className="table">
            <thead className="thead-darked">
              {
                this.props.columns.map((x: Column) => {
                  <th scope="col">{x.header}</th>
                })
              }
            </thead>
            {/* render something with this.state.dataSource */} 
          </table>
        );
        return template;
      }
    } 
    

    【讨论】:

    • 我希望一些参数是可选的,例如使用 ajaxUrl 或数据源。不是都。那可能吗?并且还可以向我展示如何仅使用 ajaxUrl 创建一个,而另一个仅使用数据源创建。会接受这个作为答案然后谢谢
    • @Alen.Toma 在这种情况下,我建议不要使用两个不同的道具,因为你不能保证只会设置两个道具中的一个。用any[] | string 输入 dataSource 属性怎么样?然后你可以通过检查typeof dataSource === 'string'来检查数据源的类型。如果是真的,它必须是一个 ajax 请求的 URL,你可以用这个 URL 做任何事情。
    • 经过一些研究后,可以添加可使用的属性吗?签署例如 datasource?: 和 ajaxUrl?:.但 typeof 仍然可以工作。
    • @Alen.Toma 您的解决方案将起作用。但正如我在上面的评论中所写,如果你让两个道具都是可选的,你必须在两个道具都未定义或两个道具都被定义时处理。
    猜你喜欢
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2019-04-01
    相关资源
    最近更新 更多