通过React.createElement

时间:2019-01-01 07:55:45

标签: reactjs

我是一名有角度的开发人员,我刚刚开始使用https://babeljs.io/repl探索react API。

我刚刚添加了CDN脚本标签以用于HTML响应,并开始探索React.createElement API。

// jsx
var e2 = <div>hello</div>;

// babel generated script
var e2 = React.createElement(
    "div",
    null,
    "hello"
);
ReactDOM.render(e2, document.getElementById('root'));

我已将babel生成的.js复制到html,并且可以正常工作。后来我开始探索props

// jsx
const e5 = <div name="taylor">{this.props.name}</div>;

// babel generated script
const e5 = React.createElement(
    "div",
    { name: "taylor" },
    this.props.name// This throws undefined
);
ReactDOM.render(e2, document.getElementById('root'));

我确定this引用了窗口对象,并且由于props未定义,因此会引发错误。那么究竟产生了什么呢?还是我缺少其他东西(关闭或上下文)?

只是好奇地知道要使它起作用的js代码是什么?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

您的问题的答案是createElement具有三个参数。

  1. 您要创建的元素的类型(例如divspanh1)或react组件。
  2. 第二个参数是您将传递给元素的属性。

    a)在这里,如果元素是React组件,则属性将传递到该组件,并且可以像在代码中一样由this.props访问。

    b)如果它是HTML元素,则将其分配给元素本身。示例:类名称,ID名称,CSS样式

  3. 最后一个参数是该组件的子代。可以是带引号的字符串,如代码中所示,在这种情况下,内容将被解释为文本。

因此,如果您这样做,您的代码将起作用:

var props = { name: "taylor" }

const e5 = React.createElement(
    "div",
    { className: "taylor", id: "asd", style: {color: 'red'} },
    'hello'+props.name
);

如果要创建一个react组件,请执行以下操作:

var Hello = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});
var props = { name: "taylor" }

const es5component = React.createElement(Hello, props)

ReactDOM.render(es5component, document.getElementById('app'));

这是现场demo

希望它会有所帮助:)

答案 1 :(得分:1)

React具有 2种方式来创建组件,即使用FunctionClass组件,您可以参考https://reactjs.org/docs/components-and-props.html

this仅适用于Class组件方式来获取props,而使用Function方式时,我们应该将props作为参数传递。

这是我的演示如何在 jsfiddle https://jsfiddle.net/huynhsamha/e9sjzndL/

上通过函数创建元素


功能组件方式

您可以使用JSX来完成

const E5 = (props) => <div>{props.name}</div> // create a component

const e5 = E5({name: 'taylor'})               // create an element

ReactDOM.render(e5, document.getElementById('root'));

Babel将会生成

const E5 = props => React.createElement(
  'div',
  null,
  props.name
);
const e5 = E5({ name: 'taylor' });

ReactDOM.render(e5, document.getElementById('root'));


类组件方式

您可以使用JSX来完成

class E6 extends React.Component {
    render() {
        return <div>{this.props.name}</div>
    }
}

const e6 = <E6 name="taylor"/>

ReactDOM.render(
  e6,
  document.getElementById('root')
);

Babel将会生成

class E6 extends React.Component {
  render() {
    return React.createElement(
      "div",
      null,
      this.props.name
    );
  }
}

const e6 = React.createElement(E6, { name: "taylor" });

ReactDOM.render(e6, document.getElementById('root'));

希望它将对您有帮助!

答案 2 :(得分:0)

如果您认为this是普通的JSX,则

<div name="taylor">{this.props.name}</div>;并没有引用任何内容(即使您尝试在https://es6console.com/上进行转换,它也没有定义)。

实际上,this不是指React.createElement的内部范围。它是指您执行this<div name="taylor">{this.props.name}</div>;的值。

例如,如果您在基于类的组件的render函数中编写相同的JSX,则this将引用该组件。并且如果其道具中包含name,它将作为参数传递给createElement。此示例详细说明。

import React, {Component} from 'react'

class MyComp extends Component {

    render () {
        // you have access to 'SomeName' in 'div' props not 'MyComp' props. but you are not defining div. right?
        return (<div name="SomeName">{this.props.name}</div>)
    }
}

class SomeOther extends Component {
    render () {
        // "TopLevelName" is available in MyComp as prop.
        return (<MyComp name="TopLevelName" />)
    }
}