类组件
// 第一步:导入react
import React from "react";
// 第二步:创建构造函数ChildTest继承 React.Component
class ChildTest extends React.Component {
render(){
return
我是class类组件
}
}
export default ChildTest
函数组件
/*
函数式组件:16.8之前-无状态组件
16.8之后-react hooks
*/
function App(){
return (
App
)
}
export default App
import { Component } from "react";
// import React from "react";
class Child extends Component{
render(){
return Child
}
}
class Navbar extends Component {
render(){
return (
Navbar
)
}
}
function Swiper(){
return Swiper
}
// 箭头函数this指向外部:提倡
const Tabbar=()=>{
return Swiper
}
class App extends Component {
render(){
return (
)
}
}
export default App
第一步:新建/css/01-index.css
.active{
background-color: blue;
}
#myapp{
background-color: pink;
}
第二步:导入类组件
// import { Component } from "react";
import React from "react";
import './css/01-index.css' //导入css模块 webpack的支持
// 推荐行内样式:因为react觉得每一个组件都是一个独立的整体
export default class App extends React.Component {
render(){
let obj = {
backgroundColor:"yellow",
fontSize:"30px"
}
return (
app组件
111111111
2222222222222
{/* 以前的class现在的className*/}
css样式测试class类名
id选择器
{/* 以前的for现在的htmlFor */}
)
}
}
// import { Component } from "react";
import React from "react";
// 推荐行内样式
export default class App extends React.Component {
state={
a:100
}
render(){
return (
)
}
handleClick2=()=>{
console.log(this,this.state.a,2)//100__有this
}
handleClick3(){
console.log(this,3) //没有this //this.handleClick3.bind(this)可改变this指向
}
handleClick4=()=>{
console.log(this,this.state.a,4)//100__有this
}
}
在state中添加一个状态,作为表单元素的value值(控制表单元素的值)
给表单元素添加change事件,设置state的值为表单元素的值(控制值的变化)
import React from "react";
export default class Ref extends React.Component {
myref =React.createRef()
render(){
return (
ref
{/* */}
)
}
handle=()=>{
// console.log(this.refs.mytext)//以前的写法
console.log(this.myref.current) //现在获取dom(input)
}
}
非受控组件借助于ref,使用原生DOM的方式来获取表单元素的值
import React from "react";
export default class App extends React.Component {
state={
mgs:10
}
render(){
return (
Controlled
)
}
handle=(e)=>{
this.setState({
mgs:e.target.value
})
console.log(this.state.mgs) //此时获取到mgs中数据为表单数据不过打印延迟一位数
}
}
setState更新数据讲解
setState() 是异步更新数据的
注意:使用该语法时,后面的 setState() 不要依赖于前面的 setState()
1. 当你调用 setState 的时候,React.js 并不会马上修改 state (为什么)
2. 而是把这个对象放到一个更新队列里面
3. 稍后才会从队列当中把新的状态提取出来合并到 state 当中,然后再触发组件更新。
可以多次调用 setState() ,只会触发一次重新渲染
this.state = { count: 1 }
this.setState({
count: this.state.count + 1
})
console.log(this.state.count) // 1
在使用 React.js 的时候,并不需要担心多次进行 setState
会带来性能问题。
推荐:使用 setState((preState) => {})
语法
参数preState: React.js 会把上一个 setState
的结果传入这个函数
this.setState((preState) => {
return {
count: preState.count + 1
}
})
console.log(this.state.count) // 1
这种语法依旧是异步的,但是state可以获取到最新的状态,适用于需要调用多次setState
场景:在状态更新(页面完成重新渲染)后立即执行某个操作
语法:setState(updater[, callback])
this.setState(
(state) => ({}),
() => {console.log('这个回调函数会在状态更新后立即执行')}
)
例如
this.setState(
(state, props) => {},
() => {
document.title = '更新state后的标题:' + this.state.count
}
)
第一种语法:this.setState({要修改的数据})
注意:不要直接修改state中的值,必须通过this.setState()
方法进行修改
class App extends React.Component {
state = {
count: 1
}
handleClick() {
this.setState({
count: this.state.count + 1
})
console.log(this.state.count)//在此处打印只能获取到数据更改前的值
}
render() {
return (
次数: {this.state.count}
)
}
}
+ 18以前
- 使用react事件触发就是一个异步
- 不使用react的事件(原生)触发就是一个同步
+ 18及以后+++++都是一个异步
第二种语法:
class App extends React.Component {
state = {
count: 1
}
handle=()=>{
this.setState(
(preState)=>{
// console.log(preState) //获取更新之前的值
return {
count:this.state.count+1
}
},
()=>{
console.log(this.state.count)//在此箭头函数中能获取到state中数据更新的最新值
}
)
}
render() {
return (
次数: {this.state.count}
)
}
}
在父组件中
在子组件中
function Hello(props) {
console.log(props)
return (
接收到数据:{props.name}
)
}
在父组件中
在子组件中
class Hello extends React.Component {
render() {
return (
接收到的数据:{this.props.age}
)
}
}
思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数。
父组件提供一个回调函数(用于接收数据)
将该函数作为属性的值,传递给子组件
子组件通过 props 调用回调函数
将子组件的数据作为参数传递给回调函数
父组件提供函数并且传递给字符串
//msg为接收到子组件传过来的数据
class Parent extends React.Component {
getChildMsg = (msg) => {
console.log('接收到子组件数据', msg)
}
render() {
return (
子组件:
)
}
}
子组件接收函数并且调用
class Child extends React.Component {
state = { childMsg: 'React' }
handleClick = () => {
this.props.getMsg(this.state.childMsg)
}
return (
)
}
**注意:回调函数中 this 指向问题!**
第一步:创建公共js文件
import React from "react";
export const {Provider,Consumer} = React.createContext()
第二步:使用 Provider 组件作为父节点。
import React from "react";
import {Provider} from "./index.js";
class App extends React.Component {
render(){
//设置 value 属性,表示要传递的数据。
return
}
}
export default App;
第三步:调用 Consumer 组件接收数据。
import { Consumer } from "./index.js";
const Child1= (props)=>{
return (
props{props.children}
//类似插槽
{(data)=>{
return data接收到的参数==={data}===
}}
)
}
export default Child1
目的:校验接收的props的数据类型,增加组件的健壮性
导入 prop-types 包
使用组件名.propTypes = {} 来给组件的props添加校验规则
校验规则通过 PropTypes 对象来指定
import PropTypes from 'prop-types'
function App(props) {
return (
Hi, {props.colors}
)
}
App.propTypes = {
// 约定colors属性为array类型
// 如果类型不对,则报出明确错误,便于分析错误原因
colors: PropTypes.array
}
常见类型:array、bool、func、number、object、string
React元素类型:element
必填项:isRequired
特定结构的对象:shape({})
// 常见类型
optionalFunc: PropTypes.func,
// 必选
requiredFunc: PropTypes.func.isRequired,
// 特定结构的对象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
场景:分页组件 每页显示条数
作用:给 props 设置默认值,在未传入 props 时生效
function App(props) {
return (
此处展示props的默认值:{props.pageSize}
)
}
// 设置默认值
App.defaultProps = {
pageSize: 10
}
// 不传入pageSize属性