深度反应 JSX
正如我们在这篇文章 React.js(介绍和工作)中看到的,React 是如何工作的,将我们的应用程序分解成更小的可重用部分,我们称之为组件。这些组件是树状 HTML 或组件结构。在那篇文章中,我们看到了如何在 react 中使用createElement创建元素。但是,如果我们必须使用 React 的 createElement 方法来创建元素,那么它可以用于演示目的或小型应用程序,但不适用于大型应用程序。你只是不应该使用它。
React.createElement 可以为小型应用程序或演示目的创建元素,但不适用于大型可销售应用程序,因为它很难维护或调试。我们每次都必须调用 React.createElement 方法来创建 React 元素,即使它只是一个没有属性的 span 标签。
您可以使用 React.createElement 方法(我不推荐)构建整个应用程序。
如果我们不应该使用createElement ,请使用 JSX。它是 JavaScript 和 XML。它是一个 JavaScript 扩展,允许我们在 JS 代码中使用基于标签的样式语法定义 React 元素。多么酷啊?
有时,新开发人员会将 JSX 与 HTML 混淆,因为它们看起来非常熟悉。 JSX 只是创建 React 元素的另一种方式。 React 团队创建了 JSX,使其像 HTML 和 XML 一样更具可读性。这样我们就不必使用createElement方法手动创建 React 元素。假设您想创建一个带有 btn 类的按钮,btn-primary。
Javascript
Javascript
Hello world
HTML
// Root element of React code
// Babel
// Our JS code
Javascript
// Opening tag of ButtonComponent
// Self closing tag because it
// doesn't have children
name
// Closing tag of ButtonComponent
Javascript
const id = Math.floor(Math.random() * 10e8); // Random number
const ButtonComponent = ( );
ReactDOM.render(ButtonComponent, document.querySelector("#root"));
Javascript
const listComponent = (
- Alex
- Ragnar
- Akbar
- Mandy
);
ReactDOM.render(
listComponent,
document.querySelector('#root')
)
/************** OR **************
const listCustomComponent = (
)
ReactDOM.render(
listCustomComponent,
document.querySelector('#root')
)
Javascript
const title = "Human beings";
const HumanComponent = (
{ title }
)
Javascript
const isHuman = true;
const IsHumanComponent = (
Ronaldo is human: { isHuman }
)
/****** OR **********\
const IsHumanComponent = (
Ronaldo is human { true }
)
Javascript
const names = ["React.js", "Angular", "Node.js", "jQuery", "underscore.js"]
const Command = (
{
names.map( function creatNameElement(name){
return
{ name }
})
}
);
ReactDOM.render(
Command,
document.querySelector('#root')
)
Javascript
function Add({a, b}) {
return (
Addition is { a + b }
)
}
function Multiplication( { a, b } ) {
return (
Subtraction is { a * b }
)
}
function Show( props ) {
const components = {
add: Add,
multiplication: Multiplication,
};
const MathComponent = components[props.type];
return (
)
}
ReactDOM.render( , document.querySelector("#root"));
Javascript
function JavaScriptExpressionAsProps({ num }) {
return (
Prop Number is: { num }
)
}
ReactDOM.render(
/* Addition is evaluated and assign its value to num */
,
document.querySelector("#root")
);
Javascript
function NameComponent({ name }) {
return (
{ name }
)
}
ReactDOM.render( ,
document.querySelector( "#root" ) );
/************ OR ***********/
ReactDOM.render( ,
document.querySelector("#root"));
/************ OR ***********/
ReactDOM.render(
,
document.querySelector("#root")
);
Javascript
function IdentifyHuman( { name, isHuman } ) {
if ( isHuman === true ) {
return { name } is human
} else {
return { name } is not human
}
}
ReactDOM.render(
,
document.querySelector("#root")
);
/************** OR ********************/
ReactDOM.render(
,
document.querySelector("#root")
);
Javascript
function PrintName( { name, isHuman } ) {
if ( isHuman === true ) {
return {name} is Human
;
} else {
return {name} is Super Human
;
}
}
function ShowHuman( props ) {
return (
Human
)
}
ReactDOM.render(
,
document.querySelector("#root")
);
Javascript
function ListComponent( props ) {
console.log( props.children ); // Child string
return (
List component
)
}
ReactDOM.render(
Child
string
,
document.querySelector("#root")
);
Javascript
function ShowList( { list } ) {
console.log( list );
return (
{ list.map( (el, index) => - { el }
) }
);
}
function ListHeading() {
return (
List component
);
}
ReactDOM.render(
This is just a dummy text
,
document.querySelector("#root")
);
Javascript
function ListComponent(props) {
props.children(); // invoke function;
return (
List component
);
}
ReactDOM.render(
{function print() {
console.log( 'This is print function passed as a child' );
}}
,
document.querySelector("#root")
);
这是 JSX 语法,看起来像 HTML,但有细微的差别,我们将在本文后面讨论。 JSX 也适用于组件,
Javascript
Hello world
下图展示了如何从React.createElement方法和JSX 组合 React Element。
从上图中,你可以清楚地看到我们可以很容易地用 JSX 创建一个 React 元素。可读性也是 React 团队实现 JSX 的简单性的主要原因。
浏览器不理解开箱即用的 JSX 语法,您必须将 JSX 代码转换/编译为 JavaScript 代码。为此,您可以使用 Babel。您可以使用脚本标签中的 CDN 链接在 HTML 文件中添加 Babel。我们必须从外部指定 Babel 应该从哪里转换。为此,我们必须在脚本标签中添加类型属性(text/babel)。
HTML
// Root element of React code
// Babel
// Our JS code
开始使用 JSX 时需要考虑一些规则:
- type:众所周知,我们必须指定React.createElement方法的第一个参数来告诉 react 我们要创建什么样的元素。在使用 JSX 创建元素时,我们必须通过将元素的类型指定为标签(类似 HTML)来告诉 react。它可以是 HTML 标签或自定义组件,例如在上图中,我们要创建一个名为Component的自定义组件,然后我们必须创建一个类似 HTML 的标签。它有 2 种口味。
- 开始和结束标签:如果我们的组件下有孩子,那么我们必须在开始和结束标签之间指定孩子。
- 自关闭:如果我们没有要指定的孩子,那么我们也可以使用自关闭标签。
Javascript
// Opening tag of ButtonComponent
// Self closing tag because it
// doesn't have children
name
// Closing tag of ButtonComponent
如果我们想创建一个没有子元素的元素,那么我们可以同时使用开始和结束标记以及自结束标记。
在后台,你所有的 JSX 都会被编译成 React.createElement。
- props:当我们使用 React.createElement 创建元素时,我们必须将其属性指定为第二个参数,但使用 JSX 我们可以将其属性指定为属性(如旧式 HTML 属性)。假设我们要为按钮指定类和 id。
Javascript
const id = Math.floor(Math.random() * 10e8); // Random number
const ButtonComponent = ( );
ReactDOM.render(ButtonComponent, document.querySelector("#root"));
在此代码片段中,我们可以看到我们已将属性指定为 ButtonComponent 的属性。
按照惯例,我们应该利用自定义组件的第一个字符。此约定不适用于内置 HTML 标签,如 span、div、h1 等。
- children:如果我们想添加组件的子组件,那么我们必须在 React 元素的开始标签和结束标签之间指定。
Javascript
const listComponent = (
- Alex
- Ragnar
- Akbar
- Mandy
);
ReactDOM.render(
listComponent,
document.querySelector('#root')
)
/************** OR **************
const listCustomComponent = (
)
ReactDOM.render(
listCustomComponent,
document.querySelector('#root')
)
JavaScript 表达式: JavaScript 的表达式应该用一个大括号括起来,并且应该指出变量在 JSX 中的求值位置。假设您要指定标题。 {title} 被评估并替换为字符串“人类”。
Javascript
const title = "Human beings";
const HumanComponent = (
{ title }
)
字符串以外的类型值也应在花括号中指定。例如
Javascript
const isHuman = true;
const IsHumanComponent = (
Ronaldo is human: { isHuman }
)
/****** OR **********\
const IsHumanComponent = (
Ronaldo is human { true }
)
由于花括号之间的表达式将被评估,因此我们也可以在连接或加法运算中使用。
{ "Hello" + "World" }
{ Math.random() * 100 }
{ [1, 2, 3, 4, 5].reduce((acc, curr) => acc + curr) }
使用 JSX 映射数组: JSX 是 javascript,因此您也可以遍历数组并使用 JSX 创建元素。
Javascript
const names = ["React.js", "Angular", "Node.js", "jQuery", "underscore.js"]
const Command = (
{
names.map( function creatNameElement(name){
return
{ name }
})
}
);
ReactDOM.render(
Command,
document.querySelector('#root')
)
输出:
在运行时选择类型:如果要指定反应元素运行时的名称,则不能使用表达式代替类型。您首先必须先创建一个大写变量,然后使用该变量代替类型。如果您想根据道具显示组件,这可能会有所帮助。
Javascript
function Add({a, b}) {
return (
Addition is { a + b }
)
}
function Multiplication( { a, b } ) {
return (
Subtraction is { a * b }
)
}
function Show( props ) {
const components = {
add: Add,
multiplication: Multiplication,
};
const MathComponent = components[props.type];
return (
)
}
ReactDOM.render( , document.querySelector("#root"));
JavaScript 表达式作为道具:您还可以将 javascript 表达式作为道具传递。为此,只需将您的道具包裹在花括号中。
Javascript
function JavaScriptExpressionAsProps({ num }) {
return (
Prop Number is: { num }
)
}
ReactDOM.render(
/* Addition is evaluated and assign its value to num */
,
document.querySelector("#root")
);
字符串字面量/模板字面量作为道具:您还可以使用字符串字面量或模板字面量作为道具。 s
Javascript
function NameComponent({ name }) {
return (
{ name }
)
}
ReactDOM.render( ,
document.querySelector( "#root" ) );
/************ OR ***********/
ReactDOM.render( ,
document.querySelector("#root"));
/************ OR ***********/
ReactDOM.render(
,
document.querySelector("#root")
);
Prop 默认为 True 布尔值:如果您想将真正的布尔值指定给组件作为道具,那么您可以在外部将true指定为值,或者您不能传递任何值,则默认值被视为 true。
Javascript
function IdentifyHuman( { name, isHuman } ) {
if ( isHuman === true ) {
return { name } is human
} else {
return { name } is not human
}
}
ReactDOM.render(
,
document.querySelector("#root")
);
/************** OR ********************/
ReactDOM.render(
,
document.querySelector("#root")
);
建议在外部指定布尔值以消除混淆。
传播属性:我们知道props只是一个 javascript 对象。如果我们想将这些所有属性原样分配给另一个组件,那么我们可以传播这些属性。
Javascript
function PrintName( { name, isHuman } ) {
if ( isHuman === true ) {
return {name} is Human
;
} else {
return {name} is Super Human
;
}
}
function ShowHuman( props ) {
return (
Human
)
}
ReactDOM.render(
,
document.querySelector("#root")
);
这是一种非常有用的技术,可以传递组件中的所有道具,但传递所有道具,但它也会传递该组件可能不需要的不需要或不必要的道具。
JSX 中的子代:在 JSX 语法中,无论您在开始和结束标记中传递什么,它都会成为子代。您可以将这些孩子视为props.children属性。
字符串字面量作为子项:我们可以使用将字符串字面量作为子项传递,它将直接将该字符串分配给道具的子项属性。 JSX 修剪开始和结束的空格或换行符。如果在字符串之间添加新行,则换行符将替换为单个空格
Javascript
function ListComponent( props ) {
console.log( props.children ); // Child string
return (
List component
)
}
ReactDOM.render(
Child
string
,
document.querySelector("#root")
);
JSX Children:如果我们想添加组件的一些子组件,那么我们必须在开始标签和结束标签之间指定。它可以是字符串,也可以是自定义组件或两者兼而有之。
Javascript
function ShowList( { list } ) {
console.log( list );
return (
{ list.map( (el, index) => - { el }
) }
);
}
function ListHeading() {
return (
List component
);
}
ReactDOM.render(
This is just a dummy text
,
document.querySelector("#root")
);
作为子函数:您也可以将函数作为子函数传递,然后我们可以使用props.children属性直接访问。
Javascript
function ListComponent(props) {
props.children(); // invoke function;
return (
List component
);
}
ReactDOM.render(
{function print() {
console.log( 'This is print function passed as a child' );
}}
,
document.querySelector("#root")
);
希望你学到了一些新东西。感谢您阅读本文。