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>
)
}
}
浙公网安备 33010602011771号