目录
TODO1
React概述
React的使用
//引入react和react-dom两个js文件
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script> 
//创建react元素
        //参数一 元素名称 参数二 元素属性 参数三 元素的子节点
         const title = React.createElement('h1',null,'hello react')
          
        //  const title = React.createElement(
        //     'p',
        //     { title: '我是标题',id:'p1'},
        //      'hello react'
        //      React.createElement('span',null,'我是span节点')
        //      )
//渲染react元素  (仅针对web开发)
         //参数一 要渲染的react元素 参数二 挂载点-》页面中指定的位置
         ReactDOM.render(title,document.getElementById('root')) 
 
React脚手架的使用
全局安装脚手架和npx安装脚手架的区别
全局安装
React脚手架的使用

npx安装
初始化项目
npx create-react-app my-app 
 
启动项目
在项目的根目录下执行** 先cd项目
npm start
 
 
在脚手架中使用React
脚手架能够帮助我们自动刷新页面
//1.导入react和react-dom两个包(非script标签导入)使用es6中的模块化语法
import React from 'react'
import ReactDOM from 'react-dom'
//2. 调用React.createElement()方法创建react元素
const title = React.createElement('p',null,'hello react')
//3. 调用ReactDOM.render()方法渲染react元素到页面中
ReactDOM.render(title,document.getElementById('')  //挂载点  
 
脚手架文件介绍
脚手架文件介绍
JSX
1. JSX的基本使用
1.1 为什么用JSX
React.createElement()过于繁琐不简洁 -》和用模板字符串一样
1.2 JSX简介
1.3 使用步骤
//1.使用JSX语法创建 React元素
const title =<h1> hello jsx</h1>
//2.使用ReactDOM.render()方法渲染react元素到页面中
ReactDOM.render(title,root) 
 
1.4 脚手架中能用JSX
1.5 注意点
2. 在JSX中使用JavaScript表达式
2.1 嵌入js表达式
2.2 注意点
const sayHi=() => 'Hi'
const title =(
    <h1>可以使用任意的函数表达式</h1>
    <span>{1}</span>
    <span>{'a'}</span>
    <span>{1+2}</span>
    <span>{3>5?1:0}</span>
    <span>{sayHi()}</span>
)
const h1=<h1>cc</h1>
const div=(
    <div> JSX自身也是js表达式 {h1} </div>
) 
 
 
3.JSX的条件渲染
//if else
         const loadData=() =>{
            if(isLoading){
                return <div>数据加载中 请稍后 </div>
            }
            return (
                <div>数据加载完成,这里显示的是数据</div>
            )
         }
         const div=(
            <div>
                {loadData()}
            </div>
         )
//三元表达式
const loadData =() =>{
return isLoading ?(<div>数据加载中</div>) :(<div>数据加载完成,这里显示的是数据</div>)
}
//逻辑与运算符 --适合要么展示 要么隐藏
const loadData=() =>{
    return isLoading &&( <div> loading</div>)
}
const div=(
            <div>
                {loadData()}
            </div>
         ) 
 
4.JSX的列表渲染
const targets =[
    {id:1,name:'react基础'},
    {id:2,name:'react进阶'},
    {id:3,name:'git+移动端开发+模块化'},
]
const list =(
    <ul>
    {targets.map(item=> <li key={item.id>{item.name}</div>)}
    </ul>
) 
 
5.JSX的样式处理
5.1 行内样式 style
//看起来像双括号 但实际上不是 外侧的表示嵌入对象 
<h1 style={{color:'red',backgroundColor: 'skyblue'}}>
    jsx样式处理
</h1>  
 
5.2 类名 className
<h1 className="title">
    jsx样式处理
</h1>
//要注意引入css文件
import 'index.css' 
 
TODO2
组件
1.组件介绍
2.组件的两种创建方式
2.1 使用函数创建组件
函数组件:使用js的函数(或箭头函数)创建的组件
//函数名称必须以大写字母开头
function Hello() {
    return (
    <div>函数组件是必须有返回值的,表示该组件的结构,返回值为null表示不渲染任何结构</div>
)
}
//渲染函数组件 -》用函数名作为组件标签名 
//组件名要大写的原因是 react据此区分普通组件和 react元素
//组件标签名 可以是单标签 也可以是双标签 
//箭头函数创建组件 
const Hello =() => (<div>函数组件</div>)
ReactDOM.render(<Hello />,root)
 
 
2.2 使用类创建组件
类组件:使用ES6的class创建的组件
//类名必须用大写字母开头
//继承React.Component父类
class Hello extends React.Component{
//必须提供render()方法
    render() {
//必须有返回值 表示该组件的结构
        return (
            <div>类组件</div>
        )
    }
}
ReactDOM.render(</Hello>,root) 
 
2.3 将组件抽离为单独的js文件
每个组件放到单独的js文件中
//Cc.js
import React from 'react'
class Cc extends React.Component{
    render() {
        return (<div> 啊啊啊啊</div>)
    }
}
//导出组件
export default Cc
//index.js
//导入组件
import Cc from '路径'
//渲染导入的组件
ReactDOM.render(<Cc />, document.getElementById('root')) 
 
事件处理
1.事件绑定
//类创建
class App extends React.Component{
    handleClick(){
    console.log('类组件中的事件绑定')
    }
    render(){
    return(
        <button  onClick={this.handleClick}> 点了会发生啥?</button>
    )
    }
}
//函数
function App() {
    function handleClick(){
    console.log('函数组件中的事件绑定')
}
 return(
 <button onClick={handleClick}>点</button>
)
}
//渲染组件
ReactDOM.render(<App />,document.getElementById('root')) 
 
2.事件对象
class App extends React.Component{
handleClick(e){
e.preventDefault()
}
render(){
    return(
    <a href="" onClick={this.handleClick}>我没加链接</a>
    )
}
}
//渲染组件
ReactDOM.render(<App/>,document.getElementById('root')) 
 
3.有状态组件和无状态组件
4.state和setState()
4.1 state的基本使用
- state是组件内部的私有数据,只能在组件内部使用
 - state的值是对象 表示一个组件中可以有多个数据
 
如何使用state
class Cc extends React.Component {
 //es6 class语法
    constructor(){
    super() //必须有 是es6的要求
    //初始化state
    this.state ={
        count :0
    }
}
//简洁版 实验性的public class fields语法
state = {
        count :0
    }
render(){
 return (
    <div>
        有组件状态
    </div>
)
}
}
 
 
①super()函数用于访问和调用一个对象上的父对象上的函数
②在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。
 super关键字也可以调用父对象上的函数。
③ES6 class语法拯救世界了吗 为什么要用它(?)
4.2 setState修改状态
this.setState({
    count:this.state.count + 1
})
//错误的
this.state.count += 1 
 
4.3 从JSX中抽离事件处理程序
this指向
1.箭头函数
①箭头函数自身不绑定this
②render方法中的this为组件实例,可以获取到setState()
箭头函数中的this指向
class Cc extends React.Component{
 onIncrement(){
    this.setState({ })
}
render(){
//箭头函数中的this指向外部环境,此处为:render() 方法
 return (
    <button onClick={() => this.onIncrement()}></button>
)
}
} 
2.Function.prototype.bind()
class Cc extends React.Component{
    constructor() {
    super()
    this.onIncrement = this.onIncrement.bind(this)
}
//省略onIncrement
render(){
 return (
    <button onClick={this.onIncrement()}></button>
)
}
} 
3.class的实例方法
①利用箭头函数形式的class实例方法
②该语法是实验性语法 但是由于babel的存在可以直接用(编译JSX的语法包)
class Cc extends React.Component{
   onIncrement =() =>{
    this.setState({...})
}
render(){
 return (
    <button onClick={this.onIncrement()}></button>
)
}
} 
4.总结
推荐使用的顺序 class的实例方法>箭头函数>bind
表单处理
1.受控组件
推荐使用受控组件来处理表单
//1.在state中添加一个状态 作为表单元素的value值(控制表单元素值的来源)
state={txt:''}
//2.给表单元素绑定change事件,将表单元素的值设置为state的值(控制表单元素值的变化)
<input type="text" value={this.state.txt}
    onChange ={e => this.setState({ txt : e.target.value })}
/> 
多表单元素优化步骤
<input
    type="text"
    name="txt"  //区分其他表单元素 名称与state相同
    value={this.state.txt}
    onChange={this.handleForm}
/>
//根据表单元素类型获取值
const value=target.type === 'checkbox'
    ?target.checked
    :target.value
//根据name设置对应的state
this.setState({
//es6的属性表达式
 [name]:value
}) 
2.非受控组件
//1.调用
constructor() {
    super()
    this.txtRef = React.createRef()
}
//2.将ref添加到文本框
<input type="text" ref={this.txtRef} />
//3.通过ref对象获取到文本框的值
console.log{this.txtRef.current.value}
//实践
class App extends React.Component{
    constructor() {
    super()
    this.txtRef = React.createRef()
}
//获取文本框的值
getTxt =() =>{
    console.log('文本框的值为:', this.txtRef.current)
}
render(){
    return(
    <div>
        <input type="text" ref={this.txtRef} />
        <button onClick={this.getTxt}获取文本框的值</button>
    </div>
)
}
}
 
完全利用js语言的能力创建组件,这是React的思想
TODO3
组件通讯
1.组件通讯的定义
因为组件时独立且封闭的单元,默认情况下,只能使用组件自己的数据,在组件化的过程中,我们要将完整的功能拆分为多个组件,这里需要共享一些数据,所以应该让组件与外界进行“通讯”
2.组件通讯的三种方式
2.1 父组件 ->子组件
①父组件提供要传递的state数据
②给子组件标签添加属性,值为state中的数据
③子组件通过props接收父组件传递的数据
2.2 子组件 ->父组件
思路:利用回调函数,父组件提供回调,子组件调用。将要传递的数据作为回调函数的参数。
①父组件提供一个回调函数(用于接收数据)
②将该函数作为属性的值,传递给子组件。
③子组件通过props调用回调函数。
④将子组件的数据作为参数传递给回调函数。
2.3兄弟组件
将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
思想:状态提升
公共父组件职责 1.提供共享状态 2.提供操作共享状态的方法
要通讯的子组件只需要通过props接收状态或操作状态的方法
props
props深入
children属性
1.表示组件标签的子节点,当组件标签有子节点时,props就会有该属性、
2.children属性与普通的props一样,值可以是任意值(文本,React元素,组件,函数)
function Hello {props}{
    return {
        <div>
            组件的子节点:{props.children}
        </div>
    }
}
<Hello> 我是子节点 </Hello> 
props校验
1.因为对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据
2.如果传入数据不对,会导致组件内部报错,且组件的使用者不知道明确的错误原因。
3.添加props校验,允许在创建组件的时候,就指定props的格式和类型。捕获使用组件时因为props导致的错误,增加组件的健壮性。
步骤
1.安装prop-types包
2.导入prop-type是包
3.使用组件名.propTypes={}给组件的props添加校验规则
4.校验规则通过PropTypes对象来指定
约束规则
1.常见类型:array bool func number object string
2.React元素类型 :element
3.必填项:isRequired
4.特定结构的对象: shape({})
//添加props校验
App.propTypes={
 a:propTypes.number,
fn:propTypes.func.isRequired,
tag:PropTypes.element,
filter:PropTypes.shape({
area:PropTypes.string,
price:PropTypes,number
})
} 
props默认值
场景:分页组件-》每页显示条数
作用:给props设置默认值,在未传入props时生效
App.defaultProps ={
 pageSize:10
}
 
Context
跨多个组件传递数据 (eg 主题 语言)
Context提供了两个组件 Provider -》用来提供数据和Consumer-》用来消费数据
//1.调用React.creatContext() 创建Provider 和Consumer 两个组件
const { Provider,Consumer} = React.createContext()
//2.使用Provider组件作为父节点
<Provider>
    <div className="App">
        <Child1 />
    </div>
</Provider>
//3.设置value属性,表示要传递的数据
<Provider value="pink">
//4.调用Consumer 组件接收数据
<Consumer>
    {data => <span>data 参数表示接收到的数据 --{data}</span>
</Consumer> 
React 官方中文文档










