渲染组件时如何使用点表示法?

IT技术 reactjs ecmascript-6 react-jsx es6-modules
2021-04-20 01:52:10

我有一个简单的组件,它应该将不同类型的字段呈现到我的表单组件中:

import React from "react";

export default class Field extends React.Component {

  render() {
    switch (this.props.type) {
      case 'textarea': {
        return (
          <div className="col-xs-12">
            <textarea
              placeholder={this.props.placeholder}
              name={this.props.name}
            >
            </textarea>
          </div>
          )
      }
      case 'text': {
        return (
          <div className="col-md-6 col-lg-4">
            <input
              type="text"
              placeholder={this.props.placeholder}
              name={this.props.name}
            />
          </div>
        )
      }
    }
  }
}

我在我的表单组件中使用这个组件,如下所示:

export default class SubmitForm extends React.Component {

  render() {
    return (
        .
        .
        .
        <Field
          type="text"
          placeholder="something"
          name="something"
        />
        <Field
          type="textarea"
          placeholder="another"
          name="othername"
        />
        .
        .
        .
    )
  }
}

我的想法是以某种方式实现我的字段组件,以便能够使用点符号,如使用点符号用于 JSX 组件中所述,我已经看到了许多其他库,我希望能够像这样使用这个组件:

<Field.Text name="sth" placeholder="sth" />
<Field.TextArea name="other" placeholder="other stuff" /> 

但我不能像 React 文档中提到的那样做。我怎样才能做到这一点?

3个回答

只需创建单个组件并以名称导出它们:

//Field.js
class TextArea extends React.Component {
  ...
}

class Text extends React.Component {
  ...
}

export { Text, TextArea };

然后从module导入所有名称:

import * as Field from './path/to/Field.js';

或者,如果您更喜欢像这样导出默认对象(这正是文档中的示例所做的,只是以不同的方式):

export default { Text, TextArea };

这将使用对象速记属性并导出默认成员——对象文字。然后你可以像这样导入它:

import Field from './path/to/Field.js';

最后:

<Field.TextArea ... />

或者,要摆脱点符号(您不能使用默认导出选项执行此操作!):

import { Text, TextArea } from './path/to/Field.js';

<Text ... />
<TextArea ... />

当然,完全按照 React 文档,您可以使用类表达式:

const Field = {
  Text: class Text extends React.Component { //you can omit the class name here
    //can be stateless functional component if you don't need state
  },
  TextArea: class TextArea extends React.Component {

  }
}

export default Field;

然后作为默认成员导入并使用点表示法。

@Taxellool 好吧,这主要是出于组织目的。他们只有一个命名空间,例如Field将所有字段类型组件组合在一起,并导出命名空间。
2021-05-24 01:52:10
所以实际上我想实现这个点符号是没有意义的。无论如何我应该创建单独的组件。并找到一种在这些组件之间共享相互事件处理程序和其他内容的方法。这是唯一的方法吗?我的意思是我见过其他库,比如 react-redux-form,它提供了类似 <Control.select> 或 <Control.textarea> 的东西。他们是否也这样做,只是以 Control 的名义出口?
2021-06-17 01:52:10
谢谢。你答案的最后一部分实际上让我理解了文档中解释的方式。无论如何,现在我没有理由再追求这个了。“点符号”的整个目的似乎是为了像你说的那样进行组织。并且必须以任何一种方式定义单独的组件。感谢您的回答。
2021-06-20 01:52:10

只需按照文档操作即可。

const Field = {
  Text: function Text(props) {
    return <div className="col-md-6 col-lg-4">
            <input
              type="text"
              placeholder={this.props.placeholder}
              name={this.props.name}
            />
          </div>;
  },
  Textarea: function Textarea(props) {
    return <div className="col-xs-12">
            <textarea
              placeholder={this.props.placeholder}
              name={this.props.name}
            >
            </textarea>
          </div>;
  }
}

然后当你的点用法

<Field.Text placeholder="something" name="something" />
export default class Field extends React.Component {

  render() {
    switch (this.props.type) {
      case 'textarea': {
        return (
          <div className="col-xs-12">
            <textarea
              placeholder={this.props.placeholder}
              name={this.props.name}
            >
            </textarea>
          </div>
          )
      }
      case 'text': {
        return (
          <div className="col-md-6 col-lg-4">
            <input
              type="text"
              placeholder={this.props.placeholder}
              name={this.props.name}
            />
          </div>
        )
      }
    }
  }
}

将其更改为以下方式

const Field = {
    text: function(){
      // your text code
    }
}

export default Field;

与他们在 facebook react文档中提到的方式相同。您可以返回包含函数的对象而不是组件。