React元素和组件(react元素和组件的区别)
一、React元素
React元素用来构建虚拟DOM(React DOM),与真实DOM有相同的树状结构,而真实DOM由DOMElement组成。
1、创建
React.createElement( type, // 必传,要创建的HTML元素标签名的字符串('div','span') [props],// 可传,元素的属性 [...children]// 可传,元素的下一层嵌套,通过React.createElement嵌套元素 ) // 示例 var child1 = React.createElement('li', null, 'one'); var child2 = React.createElement('li', null, 'two'); var content = React.createElement('ul', { className: 'teststyle' }, child1, child2); // 第三个参数可以分开也可以写成一个数组 ReactDOM.render( content, document.getElementById('example') ); 复制代码
2、JSX
使用React.createElement创建元素会造多层嵌套,JSX使创建元素更简易。
JSX:JS的一种类XML的语法扩展,提供给预处理器使用,预处理器再将其转换成React.createElement。提供{}用于编写JavaScript表达式。
class CreateComment extends Component { render() { <input value={this.state.user} /> } } 复制代码
二、React组件
将React元素组织在一起,有助于将功能、标记、样式等进行封装,方便复用。
1、有状态的React组件(React类)
创建
通过声明一个继承自 React.Component 抽象基类的JavaScript类来代表一个组件,至少需要定义render
方法,在 render
方法里面返回需要渲染的元素。
render方法可以嵌套但最高层只有一个节点,可以访问持久化的组件状态、组件方法、继承React.Component 抽象基类的方法;
class Todo extends React.Component { render() { return <li>Hello, {this.props.content}</li>; } } <Todo content="图雀" /> // 旧方式 import createReactClass from 'create-react-class'; const HelloWorld = createReactClass({ render() { return(<p>Hello, world!</p>) } }) 复制代码
状态
state:可变,在组件类定义,类实例通过this.state访问,
props:不可变不可修改,来自父组件或组件自身的defaultProps静态方法,通过this.props访问,
state的初始化和更新
state在constructor方法中进行初始化;
class CreateComment extends Component { constructor(props) { super(props); this.state = { user: "" }; } render() { <input value={this.state.user} /> } } 复制代码
React需要追踪状态并确保虚拟DOM和实际DOM同步,使用setState
更新状态;调用setState更新时,无需立即执行,而是创建一个挂起的状态转换,React选择批量更新提高效率。
React实现了一个合成事件系统作为虚拟DOM的一部分,将浏览器事件转换为React事件,这些事件设置在React元素上。
setState( updater,// 设置新状态 (prevState,props)=> stateChange [callback]// 回调函数 ) // 实例 class CreateComment extends Component { constructor(props) { super(props); this.state = { user: "" }; this.hanleUserChange =this.hanleUserChange.bind(this); } hanleUserChange(event){ const val = event.target.value; this.setState({// 浅合并 user:val }) } render() { <input value={this.state.user} onChange={this.handleUserChange}/> } } 复制代码
props的验证器PropTypes
PropTypes验证器使React类组件具有验证属性数据类型和是否必传的功能,使用时需安装prop-types包,通过将类的静态属性
或通过类定义后的简单属性赋值
添加验证。
var title = 123;// 属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 class MyTitle extends React.Component { static propTypes = {// 通过类的静态属性 title: PropTypes.string }; render() { return ( <h1>Hello, {this.props.title}</h1> ); } } MyTitle.propTypes = {// 或通过类定义后的简单属性赋值(string为类型,isRequired为必传) title: PropTypes.string.isRequired }; ReactDOM.render( <MyTitle title={title} />, document.getElementById('example') ); 复制代码
默认属性
通过为类定义一个defaultProps静态属性
添加默认属性
class MyTitle extends React.Component { static defaultProps = {// 默认属性 title: '标题' }; render() { return ( <h1>Hello, {this.props.title}</h1> ); } } ReactDOM.render( <MyTitle />, document.getElementById('example') ); 复制代码
2、无状态的函数组件
创建
// 普通函数 function HelloMessage(props) { return <h1>Hello {props.name}!</h1>; } // 箭头函数 const HelloMessage = (props) => { return <h1>Hello {props.name}!</h1>; } <HelloMessage name="Runoob"/>; 复制代码
setState执行数据的浅合并,保留任何没有被覆盖的顶级属性;
单向数据流:属性从父组件流向子组件,子组件通过回调函数将数据回送给父组件,但不能直接修改父组件的状态,父组件也无法直接修改子组件状态。组件通过属性完成组件交互。
三、ReactDOM渲染元素
ReactDOM.render( ReactElement element,// React元素 DOMElement container,// DOM元素,容器 ) 复制代码
<!--创建一个id为root的div元素,用于渲染容器--> <div id="root"></div> 复制代码
import React from "react"; import ReactDOM from "react-dom";// React渲染器,利用render方法渲染 import App from "./components/App"; ReactDOM.render( <App>, document.getElementById("root") );
作者:Janice
链接:https://juejin.cn/post/7032976675973545992