一、React元素的创建
const root=document.querySelector("#root");
let n=0;
//createElement(标签类型或者组件类型,属性,创建元素内部的东西)
const ele=React.createElement("div",{className:"red"},[
n,
React.createElement("button",{onClick:()=>{
n++;
}},"+1")
]);
//最后调用虚拟DOm渲染函数
ReactDOM.render(ele,root);
- 这个操作是创建了一个ele的ReactDom(虚拟dom),若使用,后面要调用ReactDom.Render()函数。
- ele这个元素,是个div,给其添加了class=red 属性,div的innerHtml包含了数据n和一个button元素,button元素绑定了点击后给n+1的事件。
很明显,即使点了这个button,页面的n也不会被+1,因为没有刷新渲染,即第二次调用render。
于是,
const root=document.querySelector("#root");
let n=0;
const ele=React.createElement("div",{className:"red"},[
n,
React.createElement("button",{onClick:()=>{
n++;
ReactDOM.render(ele,root); //在点击button后,再次写一个render函数,能否重新渲染呢?
}},"+1")
]);
ReactDOM.render(ele,root);
尽管点击后,n的值确实变了,但是页面也同样无法重新渲染出n。n依旧为0。
button中绑定的事件里的ReactDOM.render(ele,root)没有起到刷新的作用。
因为我们定义的ele就是一个定死的React.createElement,当const ele=之后,这行代码只只执行了一次。里面传的n就是初始的0,所以无法渲染出最新的n的值。
二、使用函数定义组件,调用组件生成元素
为了解决const ele只定义了一次的问题,我们将来ele写成函数形式。
const root=document.querySelector("#root");
let n=0;
//将ele定义为箭头函数,返回值为一个element
const Ele=()=>React.createElement("div",{className:"red"},[
n,
React.createElement("button",{onClick:()=>{
n++;
ReactDOM.render(Ele(),root); //调用Ele函数,生成最新的元素
}},"+1")
]);
ReactDOM.render(Ele(),root); //调用Ele函数,生成最新的元素
React中之所以要使用函数,因为定义了函数后,等在需要的时候调用,可以获取到最新的值
三、JSX
其实React.createElement是编译后的代码,直接写也会很长很复杂,有更简单的写法。
jsx-loader已经被babel-loader给合并了,webpack中内置了babel-loader,可直接编译html标签,将其转化为React.createElement。如上述的Ele可以写成:
//通过babel-loader,以下代码会转译为上面的第二节的js代码。
const Ele=()=>(
<div className="red">
{n}
<button onClick={()=>{
n++;
ReactDOM.render(<Ele/>,root);
}}
>
+1
</button>
</div>
) //注意return 的这一堆要用()括起来
四、条件判断与循环
1. if和else
假如n为偶数,输出<div/>,假如n为奇数,输出<span/>
vue中写法:
<template>
<div>
<div v-if="n%2===0">n为偶数</div>
<span v-else>n为奇数</span>
</div>
</template>
react中写法(直接写js):
//直接可以把标签当成一个对象去操作
const Component=()=>(
<div>
{n%2===0?<div>n是偶数</div>:<span>n是奇数</span>} //标签内用{}区分js表达式
</div>
)
//还可以
const Component=()=>{
const content=(<div>
{n%2===0?<div>n是偶数</div>:<span>n是奇数</span>} //标签内用{}区分js表达式
</div>)
return content;
}
//甚至还可以
const Component=()=>{
const inner=n%2===0?<div>n是偶数</div>:<span>n是奇数</span>;
return (
<div>
{inner}
</div>
)
}
//甚至还可以
const Component=()=>{
let inner;
if(n%2===0){
inner=<div>n是偶数</div>;
}else{
inner=<span>n是奇数</span>;
}
const content=(
<div>
{inner}
</div>
)
return content;
}
2.循环语句
假如遍历一个数组或者对象
vue中写法:
<template>
<div>
<div v-for="(n,index) in numbers" :key="index">
下标为{{index}},值为{{n}}
</div>
</div>
</template>
react中写法:
const Component=(props)=>{
return (
<div>
{props.numbers.map((n,index)=>{
return <div>下标{index}:值为{n} </div>
})}
</div>
)
}
//甚至可以用array存输出的<div/>
const Component=(props)=>{
const arr=[];
for(let i=0;i<props.numbers;i++){
arr.push(<div>下标{i}:值为{props.numbers[i]}</div>);
}
return <div>{arr}</div>;
}