props

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
props只读,无论是类式组件还是函数式组件,都不能修改props属性

  1. import React, {Component} from 'react';
  2. import { render } from 'react-dom';
  3. //React V15.5 props类型检查从react核心库分离 原来PropTypes是React核心库的内容
  4. import PropTypes from "prop-types";
  5. class HelloWorld extends Component { //类式组件
  6. //在类内部添加static属性:给类本身增加属性
  7. //在类内部添加非static属性:给类的实例对象增加对象属性 常用于初始化
  8. //在类中进行static限定
  9. static propTypes = {
  10. name:PropTypes.string.isRequired,
  11. },
  12. static defaultTypes = {
  13. name:'Li Hao',
  14. }
  15. render() {
  16. return <div>Hello {this.props.name}</div>;
  17. }
  18. }
  19. //类型检查 在类外进行限定
  20. HelloWorld.propTypes = {
  21. name:PropTypes.string.isRequired,
  22. }
  23. //对属性指定默认值
  24. HelloWorld.defaultTypes = {
  25. name:'Li Hao',
  26. }
  27. // 加载组件到 DOM 元素 mountNode
  28. render(<HelloWorld name="Lihao"/>, document.getElementById('#root'));

props.children

  1. class HelloWorld extends Component { //类式组件
  2. render() {
  3. return <div>Hello {this.props.children}</div>;
  4. }
  5. }
  6. //JSX
  7. <HelloWorld>xxx</HelloWorld>
  8. // 此时HelloWorld组件标签中的内容会被当作this.props.children 交给组件使用

state

UI = render(state)
React 把组件看成是一个状态机(State Machines)。只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

  1. class HelloWorld extends React.Component {
  2. constructor(props) { //构造函数
  3. super(props); //入参接收props必须调用super(props),否则会有意想不到的bug
  4. this.state = {date: new Date()};//构造器初始化组件状态(state)
  5. }
  6. this.state = {date: new Date()}; //初始化组件状态(state) 给类的实例对象增加属性
  7. // 在官方设计中 state的初始化应该在构造器constrcutor中执行
  8. render() {
  9. return (
  10. <div>
  11. <h1>Hello, world!</h1>
  12. <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
  13. </div>
  14. );
  15. }
  16. }

更新state

  1. //JavaScript Function
  2. //setState()接收两个参数,第一个是状态对象或者状态更新函数,第二个为执行完毕的回调函数
  3. this.setState(
  4. {attr1:'attr1'} //state Object
  5. (preState,props)={ //state update function
  6. return {attr1:preState.attr1 + 'new'} //状态更新函数 返回一个新的state对象
  7. }
  8. ,()=>{ //setState执行结束,立刻执行
  9. console.log(this.state.attr1)
  10. })
  11. //不能直接更新state
  12. this.state.date = new Date() //错误示例
  13. this.setState({date:new Date()}) //正确示例
  14. //setState异步执行 为了优化性能,React会将多个setState()合并成一个调用
  15. //如果更改的state的值并且马上要用到更改之后的值 可能获取不到想要的数据
  16. this.state = { count: 0 }
  17. incrementCount() {
  18. this.setState({
  19. count: this.state.count + 1,
  20. });
  21. }
  22. handleIncrement = () => {
  23. this.incrementCount();
  24. //x2 代码目的累加3次 无法实现
  25. }
  26. /*
  27. 需要改为回调函数形式的setState()
  28. 区别在于:传入更新函数时,就可以访问当前状态值。
  29. setState调用是 批量处理的,因此可以让更新建立在彼此之上,避免冲突。
  30. */
  31. incrementCount() {
  32. this.setState((prevState) => {
  33. return {count: prevState.count + 1}
  34. });
  35. }

setState()异步更新如何执行
截屏2022-04-04 上午12.08.57.png

refs

refs是组件内部的引用集合(reference set),收集组件内部被ref标记的标签或者其他自定义组件,以供使用
在JSX中对组件||标签进行ref标识,就会在组件的refs属性中收集到。

  1. class HelloWorld extends Component {
  2. constructor(props) {
  3. super(props);
  4. this.ref3 = React.createRef(); //React v16.3新增api 用于处理ref
  5. }
  6. getRefs(){ //处理ref的函数
  7. let ref1 = this.refs.ref1.value
  8. let ref2 = this.ref2.value
  9. let ref3 = this.ref3.current.value
  10. }
  11. render() {
  12. return
  13. <div>
  14. <input ref="ref1" /> //字符串形式ref
  15. <input ref={(ref2)=>{this.ref2 = ref2}} /> //回调函数形式ref
  16. //初次渲染时,ref的回调函数触发,入参即位当前DOM节点 将DOM传给ref2
  17. <input ref={this.ref3} /> //createRef形式ref
  18. //参考官方文档 Refs转发
  19. //我们通过调用 React.createRef创建了一个 React ref并将其赋值给ref变量。
  20. //我们通过指定ref为JSX属性,将其向下传递给React组件。
  21. //React传递ref给forwardRef内函数 (props, ref) => ...,作为其第二个参数。
  22. //我们向下转发该ref参数到,将其指定为JSX属性。
  23. //当ref挂载完成,ref.current 将指向DOM节点。
  24. //简单来说,createRef创建的的ref会通过React.forwardRef((props,ref)=>{/*JSX*/})
  25. //这样,ref就被向下转发到具体的组件中 可以binding到具体的对象上
  26. </div>;
  27. }
  28. }

参考

  1. https://www.kancloud.cn/simon_chang/react/241064 通过PropTypes 进行类型检查
  2. https://juejin.cn/post/6989941495654514718
  3. https://es6.ruanyifeng.com/#docs/class Subtitle—静态属性
  4. https://react.docschina.org/docs/state-and-lifecycle.html React官方文档—state
  5. https://segmentfault.com/a/1190000015463599 setState() 解析
  6. https://react.docschina.org/docs/forwarding-refs.html refs转发
  7. https://juejin.cn/post/6963156767937134622