【问题标题】:How do I utilize dot notation when rendering components?渲染组件时如何使用点符号?
【发布时间】:2017-12-08 13:38:07
【问题描述】:

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

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"
        />
        .
        .
        .
    )
  }
}

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

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

但我不能按照 React 文档中提到的方式进行操作。我该怎么做?

【问题讨论】:

    标签: reactjs ecmascript-6 react-jsx es6-modules


    【解决方案1】:
    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 文档中提到的方式相同。您可以返回包含您的函数的对象,而不是组件。

    【讨论】:

      【解决方案2】:

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

      //Field.js
      class TextArea extends React.Component {
        ...
      }
      
      class Text extends React.Component {
        ...
      }
      
      export { Text, TextArea };
      

      然后从模块中导入所有名称:

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

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

      export default { Text, TextArea };
      

      它将使用object shorthand properties 并导出一个默认成员——一个对象字面量。然后你可以像这样导入它:

      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;
      

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

      【讨论】:

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

      只需遵循文档即可。

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

      那么当你的dot使用时

      <Field.Text placeholder="something" name="something" />
      

      【讨论】:

        猜你喜欢
        • 2019-04-30
        • 1970-01-01
        • 2020-02-26
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 2013-01-20
        • 2018-06-28
        • 1970-01-01
        相关资源
        最近更新 更多