)
}
#### Class 关键字构建组件
```JavaScript
class HelloMessage extends React.Component {
render() {
return <h1>Hello World!</h1>;
}
}
- 区别
- 用构造函数创建出来的组件:专业的名字叫做“无状态组件”
- 用class关键字创建出来的组件:专业的名字叫做“有状态组件”
JSX 语法
JSX是一种 JavaScript 的语法扩展,是 React 官方推出的一套语法规范。他可以在 JavaScript 写 HTML 标签,JSX 这种语法,就是为了把HTML模板直接嵌入到JS代码里面,这样就做到了模板和组件关联,但是 JS 不支持这种包含 HTML 的语法,所以需要通过工具将 JSX 编译输出成 JS 代码才能使用。
// 如果要直接使用 JSX 语法,需要先安装相关的 语法转换工具
npm i babel-preset-react -D
1、如要要使用 JSX 语法,必须先运行
cnpm i babel-preset-react -D
,然后再.babelrc
中添加 语法配置;
2、JSX语法的本质:还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代码,渲染到页面上;
3、 当 编译引擎,在编译JSX代码的时候,如果遇到了<
那么就把它当作 HTML代码去编译,如果遇到了{}
就把 花括号内部的代码当作 普通JS代码去编译;
4、在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;
JSX 原理
JSX 其实就是 JavaScript 对象,JSX内部在运行的时候,也是先把 类似于HTML 这样的标签代码,
转换为了 React.createElement 的形式;也就是说:我们写了 JSX 这样的标签,也并不是直接把 我们的 HTML 标签渲染到页面上,而是先转换成 React.createElement 这样的JS代码,再渲染到页面中;
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class Header extends Component {
render () {
return (
<div>
<h1 className='title'>React 学习</h1>
</div>
)
}
}
ReactDOM.render(
<Header />,
document.getElementById('root')
)
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class Header extends Component {
render () {
return (
React.createElement(
"div",
null,
React.createElement(
"h1",
{ className: 'title' },
"React 学习"
)
)
)
}
}
ReactDOM.render(
React.createElement(Header, null),
document.getElementById('root')
);
组件嵌套
返回多个 JSX 元素必须要用一个外层的 JSX 元素把所有内容包裹起来。返回并列多个 JSX 元素是不合法的。
复用性非常强,我们可以把组件的内容封装好,然后灵活在使用在任何组件内。另外这里要注意的是,自定义的组件都必须要用大写字母开头,普通的 HTML 标签都用小写字母开头。
组件state
React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
import React from 'react';
class CollectButton extends React.Component{
constructor(){
super();
this.state = {
collect:false,
collectPrompt:"未收藏"
}
}
handleClick(){
var status = !this.state.collect
var text = status?"收藏":"未收藏";
this.setState({
collect:status,
collectPrompt:text
});
}
render(){
return(
<button onClick={()=>{
this.handleClick()
}}>{this.state.collectPrompt}</button>
);
}
}
export default CollectButton;
组件通信
React Props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
父传子
子组件定义接受数据属性名称
父组件向该属性赋值
//父组件
class Father extends React.Component {
constructor() {
super();
this.state = {
属性名称:属性值
}
}
render(){
return({
<子组件 子组件属性名称={this.state.属性名称}/>
});
}
}
//子组件接受
class Son extends React.Component{
constructor(props){
super();
this.state = props;
}
render(){
return(
<子元素标签>{this.state.子组件属性名称}</子元素标签>
);
}
}
子传父
回调函数的方式
//父组件
class Father extends React.Component {
constructor() {
super();
this.state = {
属性名称:属性值
}
}
// 父组件接受数据定于函数
getData = (需要传递给父组件的值)=>{
//拿到子组件传递给父组件的值
}
render(){
return({
<子组件 子组件属性名称={this.state.属性名称} 父组件接受数据函数名称={this.getData}/>
});
}
}
//子组件接受
class Son extends React.Component{
constructor(props){
super();
this.state = props;
}
handleClick(需要传递给父组件的值){
this.props.父组件接受数据函数名称(需要传递给父组件的值)
}
render(){
return(
<子元素标签 onClick={()=>{
this.handleClick(需要传递给父组件的值);
}}>{this.state.子组件属性名称}</子元素标签>
);
}
}
兄弟组件
通过父组件进行数据交互
跨组件通信
数据类型校验
React 获取dom
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class Index extends Component {
onClick(event){
console.log(event.target.value);
// 第一种方式
var submitObj = document.getElementById('submit');
submitObj.style.color = 'green';
// 第二种方式
ReactDOM.findDOMNode(submitObj).style.color = 'yellow';
// 第三种方式
this.refs.submit.style.color = 'blue';
}
render(){
return (
<div>
<input id='submit' ref='submit'
type='button' value='style'
onClick={this.onClick.bind(this)}/>
</div>
)
}
}
1、自定义搜索框组件
2、logo是不一样
3、搜索框提示词也是不一样的
4、搜索按钮