react基础-第二篇

102 阅读4分钟
组件通信
  • 父传子:props传数据
  • 子传父:父组件定义回调函数,传给子组件,子组件调用,
  • 兄弟通信:将公共数据交给最新的父组件管理(状态提升)
context组件的作用

跨组件传递数据,如果两个组件跨很多层级,可以使用context通信 使用:

  1. 使用createContext创建两个组件
 const {Provider,consumer}=React.createContext()
  1. 父组件节点用Provide组件(提供数据)
  2. 父组件设置value属性,表示要传递的数据
<Provider value="pink">
  1. 调用Consumer组件接受数据
<Consumer>{data=><span>data表示接受的数据:{data} </span> }</Consumer>
Props深入

children属性

  1. ①当组件有子节点,那么props就有children属性
  2. ②children属性和普通的props不同,它可以任意值(文本,元素,组件,甚至函数)
function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">Welcome</h1>
      <p className="Dialog-message">Thank you for visiting !</p>   
    </FancyBorder>
  );
}
组合与继承

组合:使用一个特殊的 children prop 来将他们的子组件传递到渲染结果中,别的组件可以通过 JSX 嵌套,将任意组件作为子组件传递给它们。

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">        Welcome      </h1>      <p className="Dialog-message">        Thank you for visiting our spacecraft!      </p>    </FancyBorder>
  );
}

继承:如果想要在组件间复用非 UI 的功能,建议将其提取为一个单独的 JavaScript 模块,如函数、对象或者类。组件可以直接引入(import)而无需通过 extend 继承它们。

Props检验

提高组件健康性,类似vue 步骤:

  1. ①安装prop-types包(npm i prop-types)
  2. ②导入包(import propTypes from "prop-type")
  3. ③使用组件名.propType={}方式添加检验规则
  4. ④检验规则通过propType来指定
// 组件.propTypes={属性: propType.类型}

Child.propTypes = {
  属性: PropTypes.string.isRequired
}
Child.defaultProps= {
  属性: 默认值
}

约束规则:

  • ①常见类型:array func bool number string object
  • ②元素类型:element
  • ③必填项:isRequired
  • ④特定结构对象 shape({})

props默认值:defaultProps 组件.defaultProps={属性:默认值}

组件的生命周期
  1. 创建时:①constructor②render③componentDidMount
  2. 更新时(setState,forceUpdate或者props发生更新):①render②componentDidUpdate
  3. 卸载时:①componentWillUnmount 注意:①render中不要调用setState②componentDidUpdate中调用setState一定要加if判断,通过参数preProps比较两次props是否相同,否则会造成死递归
组件复用:render-props以及HOC(高阶组件)

步骤:

  1. ①组件内提供复用的状态逻辑代码
  2. ②复用状态作为props.render(state)暴露到外部
  3. ③使用props.render作为要渲染的返回值 注意:并不是该模式叫render-props就一定要用render,只是为了告诉组件渲染props传来的函数,才叫做props.render模式,推荐使用children (this.props.children)
示范练习代码

组件复用:code.juejin.cn/api/raw/721…

setState说明:
  • ①推荐使用回调函数(保证每次调用的state和props都是最新的,但是该写法还是异步的)
  • ②第二个参数-回调函数(在状态更新后立即执行某个操作)
  • 组件更新机制:父组件重新渲染时也会重新渲染子组件
组件性能优化
  • ①减轻state:state只存储和组件渲染相关的数据,而对于和渲染无关的数据可以存在 this中,比如定时器的id
  • ②避免不必要的渲染(因为父组件更新会导致子组件也更新),我们可以通过shouldComponentUpdate这个钩子函数决定子组件是否需要重新渲染 shouldComponentUpdate(nextProps,nextState){ 根据条件确定是false还是true return false//表示不用重新渲染,这样是写死了,一般应该是条件} 该函数的执行时机:更新的render之前
路由基础
  • 使用步骤:
  • ①安装react-router-dom
  • ②导入三个路由的核心插件 import{BrowerRouter as router,Route,Link}from "react-router-dom"
  • ③使用Router包裹整个应用(重要)
  • ④使用Link作为导航菜单(路由入口)
- ⑤使用Route配置路由出口 ###### 常用组件说明: - ①Router包裹整个应用,一个react应用仅需使用一次 - ②router两种类型:⒈HashRouter(通过url的哈希值实现,路径有#)⒉BrowerRouter(使用h5的history这个Api,常用)
两种导航模式
声明式导航
<Link to="路由路径"/>
编程式导航:

①props.history.push(路径)②props.gistory.go(-1)

路由接收参数:this.props.match.params

路由的执行过程
  • ①点击Link组件(被转为a标签),修改了浏览器地址的url
  • ②react路由监听地址栏url的变化
  • ③react路由内部遍历所有Route组件,使用路由规则path与pathname做匹配
  • ④当path与pathname匹配成功后就展示该Route组件内容
默认路由:

表示进去页面就会匹配的路由,路径为"/"

总结:
  • ①路由可以有效管理多个视图(组件),实现SPA
  • ②react组件包裹整个应用,只需使用一次
  • ③Link是入口,Route是出口
  • ④通过props.history.push()实现路由跳转
  • ⑤默认模糊匹配,添加exact属性变成精准匹配