react基础

 

1.jsx语法

// 1.定义虚拟dom,不要写引号
// 2.标签中混入js表达式要用{}
 const myId="title"
     const myData="HELLO REACT"
    //1.创建虚拟dom
    const VDOM=(
      <h2>
        <span id={myId}>
          {myData}
          </span>
        </h2>
    )

 

// 3.样式的类名指定不要用class,要用className
 // 4.内联样式,要用style={{key:value}}的形式去写

<style> .title{ background-color: red; } </style> const VDOM=( <div> <h1 className="title" id="{id}"> <span style={{fontSize:'30px'}} >HELLO REACT</span> </h1> </div> )
 // 5.虚拟dom 必须只有一个根标签
 //6.标签必须闭合
    const VDOM=(
       <div>
          <h1 className="title" id="{id}">
          <span style={{fontSize:'30px'}} >HELLO REACT</span>
          </h1>
           <input type="password" name="" id="" >  // 报错
          </div>
          <div></div> // 会报错
      )
 // 7.标签首字母:
     // 若为小写,会将该标签转化为html同名元素,若HTML没有对应的同名元素,会报错
     //若为大写,会渲染对应的组件
    
  <div>
          <h1 className="title" >
          <span style={{fontSize:'30px'}} >HELLO REACT</span>
          </h1>
    <good>123</good> //会报错
   <Good></Good>
          </div>

 

  // 8 数组循环渲染用map
const data=["vue","react","anguler"]
    //1.创建虚拟dom
    const VDOM=(
       <div>
         <ul>
          {data.map((item,index)=>{
          return  <li key={index}>{item}</li>
          })}
          </ul>
          </div>)

 

2.全局安装react脚手架及创建项目

  npm install -g create-react-app

  create-react-app + 项目名字

 

 

3.函数是组件

//1 首字母必须大写
function Demo () {
  return (
    <div>
      <h2>函数式组件</h2>
      <span>123123</span>
    </div>
  )
}
export default Demo
//react解析组件标签,找到Demo组件
  // 发现组件是使用函数定义,随后调用该函数,将返回的虚拟dom转化成真是dom,随后渲染到页面上

4.类似组件

import React from "react";
class MyCompnent extends React.Component {
  render () {//放在MyCompnent的原型对象上供实列使用 render中的this指向MyCompnent组件实列对象
    return <div>hello react
      <h2> react</h2>
    </div>
  }
}
export default MyCompnent
  //react解析组件标签,找到MyCompnent组件
  // 发现组件是使用类定义,随后new出该类的实列,并通过该实例调用原型上的render方法
  //将render返回的虚拟dom转化成真是dom,随后渲染到页面上

 5.组件样式

import React, { Component } from "react";
import "../css/index.css"

export default class App extends Component {
  render () {
    let obj = { //驼峰命名
      backgroundColor: "red",
      fontSize: "30px"
    }
    return (
      <div style={obj}>
        hello React
        <div className="active">sdfsdf</div>
      </div>
    )
  }
}

6.事件绑定

import React, { Component } from "react";
export default class App extends Component {
  a = 444
  render () {
    return <div>
      <button onClick={this.handleClick}>add</button>
      <button onClick={() => this.handleClick()}>add1</button>
    </div>
  }
  handleClick = () => {
    console.log(this.a);
  }
  // 需要传参必须使用() => this.handleClick()方式
}

 7.ref的使用

import React, { Component } from "react";
export default class App extends Component {
  a = 444
  myRef = React.createRef() //返回一个ref对象
  render () {
    return <div>
      <input ref={this.myRef} />
      <button onClick={() => this.handleClick()}>add1</button>
    </div>
  }
  handleClick = () => {
    console.log(this.a);
    // console.log(this.refs.myText.value);
    console.log(this.myRef.current.value);
  }
}

8.状态(state)的使用

import React, { Component } from "react";
export default class App extends Component {
  state = {
    isShow: true,
    count: 1
  }
  render () {
    return <div>
      <button onClick={() => {
        this.handleClick()
      }}>{this.state.isShow ? "收藏" : "取消收藏"}</button>
      <div>{this.state.count}</div><button onClick={this.handleAdd1}>add1</button>

    </div>
  }
  handleClick = () => {
    const isShow = this.state.isShow
    this.setState({
      isShow: !isShow
    })
    console.log('被输出值{  }的输出结果是:', this);
  }
  handleAdd1 = () => {
    this.setState({   //setState是异步更新的
      count: this.state.count + 1
    }, () => {
      console.log(this.state.count);//2
    })

    console.log(this.state.count);//1

  }

}

9.简单的todolist案例

import React, { Component } from "react";
export default class App extends Component {

  myRef = React.createRef() //返回一个ref对象

  state = {
    list: ["wqeqwe", "aaa", "dddd"]
  }
  render () {
    return <div style={{ margin: "50px 200px" }}>
      <input ref={this.myRef} />
      <button onClick={() => this.handleAdd()}>add</button>

      <ul>
        {this.state.list.map((item, index) => {
          return <li onClick={() => this.handleDel(index)} key={index}>{item}</li>
        })}
      </ul>
      {/* {条件渲染} */}
      {this.state.list.length === 0 ? <div>暂无数据</div> : null}
    </div>
  }
  /**
   * 添加
   */
  handleAdd = () => {
    const newList = [...this.state.list]
    newList.push(this.myRef.current.value)
    this.setState({
      list: newList
    })
    this.myRef.current.value = ""
  }
  /**
   * 删除
   */
  handleDel = (index) => {
    const newList = [...this.state.list]
    newList.splice(index, 1)
    this.setState({
      list: newList
    })
  }
}

 10.属性(props)之父子组件通讯

//父组件
import React, { Component } from "react";
import NavBar from "../component/nav-bar";
import SideBar from "../component/side-bar";
export default class App extends Component {
  state = {
    count: 1
  }
  myRef = React.createRef()
  render () {
    return <div>
      {/* <h2>首页</h2> */}

      <NavBar ref={this.myRef} title="首页" event={(data) => this.handleEvent(data)} count={this.state.count} isShow={false}></NavBar>
      <button onClick={() => {
        console.log('被输出值{  }的输出结果是:', this.myRef);
        //通过ref修改子组件的状态
        this.myRef.current.setState({
          num: this.myRef.current.state.num + 1
        })
      }}>修改子组件num</button>
      <SideBar bg="red"></SideBar>
    </div>
  }
  //字传父回调
  handleEvent = (data) => {
    console.log('被输出值{  }的输出结果是:', data);
    this.setState({
      count: this.state.count + data
    })
  }

}
//子组件类式组件
import React, { Component } from "react";
import types from "prop-types"
export default class NavBar extends Component {

  state = {
    num: 2
  }
  //属性验证
  static propTypes = { //类属性,通过类直接访问
    title: types.string,
    count: types.number,
    isShow: types.bool
  }
  //属性设置默认值
  static defaultProps = {
    title: "",
    count: 0,
    isShow: false
  }

  render () {
    const { title, count, isShow } = this.props
    return <div style={{ display: 'flex', margin: "20px" }}>
      <div> {title}</div>
      <div style={{ margin: "0 20px" }}>{count}</div>
      {isShow ? <button >显示与隐藏</button> : null}
      <button onClick={() => {
        //不能直接修改props
        // this.props.count = 2
        //字传父
        this.props.event(2)
      }}>修改父组件的count</button>
      <div>{this.state.num}</div>

      {/* { 属性是只读的,不能修改} */}
    </div>
  }
}

//子组件函数是组件
import React from 'react'
import types from "prop-types"
function SideBar (props) {
  console.log('被输出值{  }的输出结果是:', props);
  const { bg } = props
  return (
    <div style={{ background: bg, width: "150px" }}>
      <ul>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
        <li>1233</li>
      </ul>
    </div>
  )
}

export default SideBar
//属性验证
SideBar.propTypes = {
  bg: types.string
}
//默认值
SideBar.defaultProps = {
  bg: "pink"
}

 11.非父子组件通信发布订阅者模式

/* eslint-disable no-useless-constructor */
/* eslint-disable import/first */
//简单的发布订阅者模式
let bus = {
  list: [],
  //先订阅
  serscribe (callback) {
    this.list.push(callback)
  },

  // 再发布
  publish (data) {
    this.list.forEach(callback => {
      callback && callback(data)
    })
  }
}




import React, { Component } from 'react'

// 父组件
export default class publish extends Component {
  render () {
    return (
      <div>
        <Children1 />
        <Children2 />
      </div>
    )
  }
}

// 子组件1订阅
class Children1 extends Component {
  state = {
    count: 0
  }
  //生命周期挂载后
  componentDidMount () {
    bus.serscribe((data) => {
      this.setState({
        count: this.state.count + data
      })
    })
  }

  render () {
    return (
      <div>{this.state.count}</div>
    )
  }
}


// 子组件2发布
class Children2 extends Component {
  state = {
    num: 1
  }
  render () {
    return (
      <div >
        <button onClick={() => {
          bus.publish(this.state.num)
        }}>发布</button>
      </div>
    )
  }
}

12.祖孙组件通信context

import React, { Component } from 'react'
const GlobleContext = React.createContext()
// 父组件
export default class context extends Component {
  state = {
    num: 0
  }
  render () {
    return (
      <GlobleContext.Provider value={{
        son: "儿子",
        child: "孙子",
        change: (data) => {
          this.setState({
            num: this.state.num + data
          })
        }

      }}>
        <div>
          {this.state.num}
          <ContextSon />
        </div>
      </GlobleContext.Provider>
    )
  }
}



// 子组件
class ContextSon extends Component {
  render () {
    return (
      <GlobleContext.Consumer>
        {(value) => {

          return <div>
            {value.son}
            <ContextChild />
          </div>
        }}
      </GlobleContext.Consumer>
    )
  }
}

// 孙组件
class ContextChild extends Component {
  render () {
    return (
      <GlobleContext.Consumer>
        {(value) => {
          console.log('被输出值{  }的输出结果是:', value);
          return <div>{value.child}

            <button onClick={() => {
              value.change(1)
            }}>孙组件修改父组件状态</button>
          </div>
        }}
      </GlobleContext.Consumer>
    )
  }
}

 

posted @ 2022-10-12 22:52  chenxianli  阅读(49)  评论(0)    收藏  举报