Javascript 是否可以创建为父组件提供配置的子节点?

Javascript 是否可以创建为父组件提供配置的子节点?,javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,我希望这样做的场景是创建一个通用的datagrid组件。我希望使用子级定义网格的列,但我不希望这些子级进行渲染,因为渲染逻辑被抽象为网格结构的表示(下面的视图属性) i、 e。, 当然!看一看这种配置风格的示例。也就是说,我认为它更适合嵌套的东西(比如路由配置);否则,我建议只使用更以JavaScript为中心的样式定义对象或对象数组来配置网格 在您的示例中,mycl不需要渲染,您只需要内省创建它时使用的属性。下面是一个例子: var MyDataGrid = React.createCla

我希望这样做的场景是创建一个通用的datagrid组件。我希望使用子级定义网格的列,但我不希望这些子级进行渲染,因为渲染逻辑被抽象为网格结构的表示(下面的视图属性)

i、 e。,

当然!看一看这种配置风格的示例。也就是说,我认为它更适合嵌套的东西(比如路由配置);否则,我建议只使用更以JavaScript为中心的样式定义对象或对象数组来配置网格

在您的示例中,
mycl
不需要渲染,您只需要内省创建它时使用的属性。下面是一个例子:

var MyDataGrid  = React.createClass({
  render: function() {
    var options = React.Children.map(this.props.children, (child) => {
      return {
        type: child.type.displayName,
        sortable: !!child.props.sortable,
        fieldName: child.props.fieldName
      };
    });
    return <pre>{JSON.stringify(options, null, "  ")}</pre>
  }
});

var MyCol = React.createClass({
  render: function() {
    return null;
  }
});

var app = (
  <MyDataGrid>
    <MyCol fieldName='asdf' sortable />
    <MyCol fieldName='anotherColumn' />
  </MyDataGrid>
);

ReactDOM.render(app, document.getElementById("app"));
var MyDataGrid=React.createClass({
render:function(){
var options=React.Children.map(this.props.Children,(child)=>{
返回{
类型:child.type.displayName,
可排序:!!child.props.sortable,
字段名:child.props.fieldName
};
});
返回{JSON.stringify(选项,null,“”)}
}
});
var MyCol=React.createClass({
render:function(){
返回null;
}
});
变量应用=(
);
render(app,document.getElementById(“app”));

示例:

处理配置子组件的主要问题是,当您在父组件中接收子组件道具时,react组件类将不会调用其构造函数。如果您有任何与需要应用的配置节点/组件相关联的逻辑,这会使事情变得复杂

我现在使用的模式如下所示(并已确认如您所期望的那样工作)。我对组件使用ES6类,但该模式也适用于功能
React.create*
样式

  • 创建道具接口(定义可在配置子节点中使用的道具)
  • 创建一个虚拟组件类,该类使用您创建的道具(该组件实际上只是一个定义,不包含任何代码)
  • 使用使用所有道具并执行任何初始化逻辑的构造函数创建配置类
  • 将静态
    create
    函数添加到使用
    ReactElement
    的配置类中,并返回配置类的新实例(该元素将具有jsx/tsx中定义的道具)
  • 使用
    React.Children.map
    将子道具转换为父级中的配置实例数组(这可以在
    componentWillMount
    中完成,并保存到实例变量中,除非列定义是可变的)
  • 简化示例(在Typescript中)

    接口IDataGridColumnProps{
    字段名:字符串;
    标题?:字符串;
    可排序?:布尔值;
    }
    导出类DataGridColumn扩展React.Component{}
    类列{
    构造函数(公共字段名:string,public header?:string,public sortable=false){
    if(this.header==null){
    this.header=this.fieldName;
    }
    }
    公共静态创建(元素:React.ReactElement){
    返回新列(element.props.fieldName、element.props.header、element.props.sortable);
    }
    }
    导出类DataGridView/*…*/{
    私有列:列[];
    组件willmount(){
    this.columns=React.Children.map(this.props.Children,(x:React.ReactElement)=>{
    返回列。创建(x);
    });
    }
    }
    

    上面使用的模式本质上是将组件节点转换为父组件上的配置实例。原始子节点被抛出,它们提供的配置保留在父组件内的实例数组中。

    在这种情况下,我建议不要在chil中使用呈现逻辑dren而是将父级(网格组件?)传递函数作为子级调用的道具。这就是我目前正在做的,但这意味着我必须作为道具(看起来不好)而不是子节点(看起来不错)传递配置逻辑。感谢您让我更仔细地了解React Router,答案肯定在他们的代码库中。虽然我尝试做了类似的事情,但没有成功,但React Router使用的构造模式造成了差异。
    interface IDataGridColumnProps {
      fieldName: string;
      header?: string;
      sortable?: boolean;
    }
    
    export class DataGridColumn extends React.Component<IDataGridColumnProps, any> {}
    
    class Column {
      constructor(public fieldName: string, public header?: string, public sortable = false) {
        if (this.header == null) {
          this.header = this.fieldName;
        }
      }
    
      public static create(element: React.ReactElement<IDataGridColumnProps>) {
        return new Column(element.props.fieldName, element.props.header, element.props.sortable);
      }
    }
    
    export class DataGridView /* ... */ {
      private columns: Column[];
    
      componentWillMount() {
        this.columns = React.Children.map(this.props.children, (x: React.ReactElement<IDataGridColumnProps>) => {
          return Column.create(x);
        });
      }
    }