props
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
props只读,无论是类式组件还是函数式组件,都不能修改props属性
import React, {Component} from 'react';import { render } from 'react-dom';//React V15.5 props类型检查从react核心库分离 原来PropTypes是React核心库的内容import PropTypes from "prop-types";class HelloWorld extends Component { //类式组件//在类内部添加static属性:给类本身增加属性//在类内部添加非static属性:给类的实例对象增加对象属性 常用于初始化//在类中进行static限定static propTypes = {name:PropTypes.string.isRequired,},static defaultTypes = {name:'Li Hao',}render() {return <div>Hello {this.props.name}</div>;}}//类型检查 在类外进行限定HelloWorld.propTypes = {name:PropTypes.string.isRequired,}//对属性指定默认值HelloWorld.defaultTypes = {name:'Li Hao',}// 加载组件到 DOM 元素 mountNoderender(<HelloWorld name="Lihao"/>, document.getElementById('#root'));
props.children
class HelloWorld extends Component { //类式组件render() {return <div>Hello {this.props.children}</div>;}}//JSX<HelloWorld>xxx</HelloWorld>// 此时HelloWorld组件标签中的内容会被当作this.props.children 交给组件使用
state
UI = render(state)
React 把组件看成是一个状态机(State Machines)。只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
class HelloWorld extends React.Component {constructor(props) { //构造函数super(props); //入参接收props必须调用super(props),否则会有意想不到的bugthis.state = {date: new Date()};//构造器初始化组件状态(state)}this.state = {date: new Date()}; //初始化组件状态(state) 给类的实例对象增加属性// 在官方设计中 state的初始化应该在构造器constrcutor中执行render() {return (<div><h1>Hello, world!</h1><h2>It is {this.state.date.toLocaleTimeString()}.</h2></div>);}}
更新state
//JavaScript Function//setState()接收两个参数,第一个是状态对象或者状态更新函数,第二个为执行完毕的回调函数this.setState({attr1:'attr1'} //state Object(preState,props)={ //state update functionreturn {attr1:preState.attr1 + 'new'} //状态更新函数 返回一个新的state对象},()=>{ //setState执行结束,立刻执行console.log(this.state.attr1)})//不能直接更新statethis.state.date = new Date() //错误示例this.setState({date:new Date()}) //正确示例//setState异步执行 为了优化性能,React会将多个setState()合并成一个调用//如果更改的state的值并且马上要用到更改之后的值 可能获取不到想要的数据this.state = { count: 0 }incrementCount() {this.setState({count: this.state.count + 1,});}handleIncrement = () => {this.incrementCount();//x2 代码目的累加3次 无法实现}/*需要改为回调函数形式的setState()区别在于:传入更新函数时,就可以访问当前状态值。setState调用是 批量处理的,因此可以让更新建立在彼此之上,避免冲突。*/incrementCount() {this.setState((prevState) => {return {count: prevState.count + 1}});}
refs
refs是组件内部的引用集合(reference set),收集组件内部被ref标记的标签或者其他自定义组件,以供使用
在JSX中对组件||标签进行ref标识,就会在组件的refs属性中收集到。
class HelloWorld extends Component {constructor(props) {super(props);this.ref3 = React.createRef(); //React v16.3新增api 用于处理ref}getRefs(){ //处理ref的函数let ref1 = this.refs.ref1.valuelet ref2 = this.ref2.valuelet ref3 = this.ref3.current.value}render() {return<div><input ref="ref1" /> //字符串形式ref<input ref={(ref2)=>{this.ref2 = ref2}} /> //回调函数形式ref//初次渲染时,ref的回调函数触发,入参即位当前DOM节点 将DOM传给ref2<input ref={this.ref3} /> //createRef形式ref//参考官方文档 Refs转发//我们通过调用 React.createRef创建了一个 React ref并将其赋值给ref变量。//我们通过指定ref为JSX属性,将其向下传递给React组件。//React传递ref给forwardRef内函数 (props, ref) => ...,作为其第二个参数。//我们向下转发该ref参数到,将其指定为JSX属性。//当ref挂载完成,ref.current 将指向DOM节点。//简单来说,createRef创建的的ref会通过React.forwardRef((props,ref)=>{/*JSX*/})//这样,ref就被向下转发到具体的组件中 可以binding到具体的对象上</div>;}}
参考
- https://www.kancloud.cn/simon_chang/react/241064 通过PropTypes 进行类型检查
- https://juejin.cn/post/6989941495654514718
- https://es6.ruanyifeng.com/#docs/class Subtitle—静态属性
- https://react.docschina.org/docs/state-and-lifecycle.html React官方文档—state
- https://segmentfault.com/a/1190000015463599 setState() 解析
- https://react.docschina.org/docs/forwarding-refs.html refs转发
- https://juejin.cn/post/6963156767937134622
