###react安装
create-react-app是你开始构建一个全新单页面应用的最好方式
npm install -g create-react-appcreate-react-app my-react-appcd my-appnpm start复制代码
// 1.render的含义就是把一个React元素渲染到指定的Dom容器中去;// 2.react是一个用户构建界面的js库;//jsx是JavaScript+html的混合写法// render 函数里面额元素标签样式声明 className = class style={ {backgroundColor:'red'}},ReactDOM.render(hello, document.querySelector('#root'))复制代码
React是由react元素和组件组成的;
2.组件定义的第一中方式函数(函数定义的组件是静态的,不能动)
## 组件定义的第一种方式是函数定义import React from 'react';import ReactDOM, {render} from 'react-dom';**组件的首字母必须大写****组件定义完后可以像React元素一样使用**函数组件的渲染过程:1.封装props对象;2.调用组件函数,得到返回的react标签元素;只有react元素才可以渲染页面;3.ReactDOM把React元素转化成真是的dom元素,插入到指定的容器中;默认我们给组件传递的属性,都会被一个对象接受,参数就是一个属性对象let Message = (props) => { console.log(props)//{msg: 'hell0', id: '2'} return{props.msg}
}render(,window.app)复制代码
3.组件定义的第二种方式(通过类来声明组件)
import React,{Component} from 'react';// Component是react属性import {render} from 'react-dom';我们通过类声明组件,Clock类继承Componentclass Clock extends Component { constructor () { super() ## 自定义组件状态对象 ## 状态(state)可以用来存放组件内部一些变化的值,状态只能由内部初始化,内部改变; this.state = {time: new Date().toLocaleString()} } // 声明周期函数 componentDidMount () { setState有两个功能: 一是覆盖老的状态, 二是会从新调用render方法重新渲染 window.setInterval(() => { this.setState({time: new Date().toLocaleString()}) },1000) } render方法指的是该组件如何渲染,一定要返回一个react元素, 而且只能返回一个react元素; render(){ return{this.state.time}
}}render(,document.querySelector('#root'))复制代码
4.react组件属性
import React, {Component} from 'react';import {render} from 'react-dom';import PropTypes from 'prop-types'怎么定义属性,获取属性,传递属性,属性的类型## 状态state:自己在组件内部定义的属性,在组件内部可以操作改变,外部不可操作,通过setState()方法修改state状态;## 属性props:从组件外部传入到组件,在组件内部只可读,不可改变的;class Person extends Component{ constructor () { super() // 为组件添加一个初始的状态 this.state = {happy: true} } // 指定默认属性对象的默认值 static defaultProps = { name: 'wu ming' } // 如何定义组件传入的属性指定类型和必传性 static propTypes = { name: PropTypes.string, age: PropTypes.number.isRequired } handleClick = () => { this.setState({ happy: !this.state.happy }) } // render方法是react的核心方法,dom渲染什么元素,就看render返回什么元素 ##这里的render是组件的一个方法 render() { //console.log(this) let header = this.state.happy ? '开心': '不开心' return () }}##这里的render是reactDom的属性,处理react里面的元素,处理成dom可以识别的dom元素,插入到指定的容器中;render(姓名:{this.props.name}
心情:{header}
,document.querySelector('#root'))复制代码
5.受控组件DOM操作
import React, {Component} from 'react';import {render} from 'react-dom';##受控组件:就是input,checkbox,textare,form表单组件,实现数据的双向绑定(受当前状态控制)##非受控组件:不受状态控制## 1.input的value值等于state的val值,所以我们的input受state控制,只有我们的state里面的val发生改变我们的input值才会有所改变;## 2.我们通过input onChange事件取到当前input的value值,然后在赋值给我们的state状态里面的val,进而我们input的value发生改变;class Input extends Component { constructor () { super() this.state = {val: ''} } handerChange = (event) => { let val = event.target.value this.setState({val}) } // 元素渲染 render () { return () }}##受控组件dom操作案例2class Input extends Component { constructor () { super() this.state = {a:'',b:'',result:''} } handleChangeA = (event) => { this.setState({ a: parseInt(event.target.value), result:parseInt(event.target.value) + this.state.b, }) } handleChangeB = (event) => { this.setState({ b:parseInt(event.target.value), result: this.state.a+parseInt(event.target.value), }) } // 渲染元素 render () { return ({this.state.value}
+ =) }}复制代码
6.非受控组件DOM操作
import React, {Component} from 'react';import {render} from 'react-dom';//受控组件:就是input,checkbox,textare,form表单组件,实现数据的双向绑定(受当前状态控制)//非受控组件:class Input extends Component { constructor () { super() } handleChangeA = (event) => { //this.refs.result.value = parseInt(this.refs.a.value||0)+ parseInt(this.refs.b.value||0) // 调用ref等于一个函数,react元素转化dom元素,渲染到页面,立即执行该函数,将渲染后的dom传入到该函数中; this.result.value = parseInt(this.a.value||0)+ parseInt(this.b.value||0) } // 渲染元素,利用事件冒泡的机制传播绑定给父元素 // ref等于一个函数的时候,表示当前元素挂在到页面中之后会立即调用此函数,并传入渲染后的dom元素; render () { return (this.a = ref}/>+ this.b = ref}/>= this.result = ref} />) } // render () { // return ( //// + // = // //// ) // }}//这里的render是reactDom的属性,处理react里面的元素,处理成dom可以识别的dom元素,插入到指定的容器中;render(,document.querySelector('#root'))复制代码
7.复合组件
import React, {Component} from 'react';import {render} from 'react-dom';import 'bootstrap/dist/css/bootstrap.css'// 组件的嵌套(复合组件)// 单项数据流:就是父组件像子组件传递参数;一层层传递,不可以直接传递给孙组件;class Panel extends Component { constructor () { super() this.state ={ col: '' } } handleRed = () => { this.setState({ col: 'red' }) } handleGreen = () => { this.setState({ col: 'green' }) } render () { return () }}class PanelHead extends Component { render () { return ( {this.props.header}) }}class PanelBody extends Component { render () { return ({this.props.body}) }}class PanelFooter extends Component { render () { return ({this.props.footer}) }}render(,document.querySelector('#root'))复制代码
8.组件的声明周期函数
import React, {Component} from 'react';import {render} from 'react-dom';import 'bootstrap/dist/css/bootstrap.css'// 组件的声明周期 代码编写的顺序class Counter extends Component { constructor () { super() this.state = {num:0} } // 组件将要被挂载(react元素在插入页面之前) componentWillMount () { console.log('1.组件将要被挂在') } componentDidMount () { console.log('3.组件挂载完成') } // 组件是否要因为props和state的变化要渲染,true为渲染,false则不渲染 shouldComponentUpdate (newProps,newState) {// 新的属性对象,新的状态对象 console.log('4.组件是否要更新,提供一个setState方法是否要触发render,重新渲染') //它有一个返回值,返回true就渲染,执行render方法,刷新页面,否则就不渲染(我们用返回值来决定是否要刷新页面) if (newState.num%5 === 0) { return true } else { return false } } componentWillUpdate () { console.log('5.组件将要更新') } componentDidUpdate () { console.log('6.组件更新完成') } handleClick = () => { // setState方法是异步操作,切记不能在赋值后立即获取最新的state值,我们要在setState的第二个参数回调函数中获取 this.setState({ num: this.state.num+1 }, () => { //console.log(this.state.num) }) } render () { console.log('2.react元素插入页面,组件挂在到页面') return () }}// 子的组件class SubCounter extends Component { // 组件将要接受到新的属性对象,来自父组件的改变,将会重新执行render方法 componentWillReceiveProps () { console.log('7.接受到父组件的变动,props变动') } shouldComponentUpdate (newProps,newState) {// 我们的newProps发生变化 if (newProps.num %10 === 0) { return true } else { return false } } render () { // 我们的props的来自父组件的state状态 return ({this.state.num}
) }}render({this.props.num}
,document.querySelector('#root'))复制代码