【React】React之从基础到放弃

React之从基础到放弃 

  生命的过程,无论是阳春白雪,青菜豆腐,我都得尝尝是什么滋味,才不枉来走这么一遭啊!      ——三毛

【React】React之从基础到放弃_第1张图片


前言

本文非从零开始学习react,只针对新手在使用时务必知晓的知识点,若要学习从零开始使用react,可移步react中文教程,再来查看此文章


正文

1、父组件调用子组件方法

通过props传入方法,接收子组件传回的this。其实就类似react的ref属性的使用

import React, { Component } from "react";

export default class Parent extends Component {
  render() {
    return (
      
); } onRef = ref => { this.child = ref; }; click = e => { this.child.myName(); }; } class Child extends Component { componentDidMount() { this.props.onRef(this); } myName = () => alert("xiaohesong"); render() { return "woqu"; } }

2.JSX中事件直接传参

 handleClick(porps0, props1, ..., event) { // your code here }

3.显示html

【React】React之从基础到放弃_第2张图片

4.聚焦

【React】React之从基础到放弃_第3张图片

 

5.单向数据流

props传的属性是只读对象

为什么需要单向,不让子组件修改?

【React】React之从基础到放弃_第4张图片

 

答:A,B,C,D中操作数据时,发生错误,不好定位是哪里修改了父组件数据(list),数据操作也更加清晰

6.react是视图层框架

【React】React之从基础到放弃_第5张图片

 

紫色组件想与右上角组件数据通信,只能通过一层一层调用上面的组件方法传值,再通过属性向下传递。解决方法是与redux,mobx等数据层框架进行搭配,更加灵活。

7.函数式编程,更容易自动化测试

8.属性类型校验

【React】React之从基础到放弃_第6张图片

 

9.由于 JSX 编译后会调用 React.createElement 方法,所以在你的 JSX 代码中必须首先声明 React 变量。

【React】React之从基础到放弃_第7张图片

推荐去在线编译网站实践:babel在线编译

10.在运行时动态渲染组件不同类型

你不能使用表达式来作为 React 元素的标签。如果你的确想通过表达式来确定 React 元素的类型,请先将其赋值给大写开头的变量。这种情况一般会在你想通过属性值条件渲染组件时出现:

import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

function Story(props) {
  // 错误!JSX 标签名不能为一个表达式。
  return ;
}

要解决这个问题,我们需要先将类型赋值给大写开头的变量。

import React from 'react';
import { PhotoStory, VideoStory } from './stories';

const components = {
  photo: PhotoStory,
  video: VideoStory
};

function Story(props) {
  // 正确!JSX 标签名可以为大写开头的变量。
  const SpecificStory = components[props.storyType];
  return ;
}

11.子代

在包含开始和结束标签的 JSX 表达式中,标记之间的内容作为特殊的参数传递:props.children。有几种不同的方法来传递子代:

  • 字符串常量

你可以在开始和结束标签之间放入一个字符串,则 props.children 就是那个字符串。这对于许多内置 HTML 元素很有用。例如:

Hello world!

这是有效的 JSX,并且 MyComponent 的 props.children 值将会直接是 "hello world!"。因为 HTML 未转义,所以你可以像写 HTML 一样写 JSX:

This is valid HTML & JSX at the same time.
  • 函数

通常情况下,插入 JSX 中的 JavaScript 表达式将被认作字符串、React 元素或这些内容的列表。然而,props.children 可以像其它属性一样传递任何数据,而不仅仅是 React 元素。例如,如果你使用自定义组件,则可以将调用 props.children 来获得传递的子代:

// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
  let items = [];
  for (let i = 0; i < props.numTimes; i++) {
    items.push(props.children(i));
  }
  return 
{items}
; } function ListOfTenThings() { return ( {(index) =>
This is item {index} in the list
}
); }

传递给自定义组件的子代可以是任何元素,只要该组件在 React 渲染前将其转换成 React 能够理解的东西。这个用法并不常见,但当你想扩展 JSX 时可以使用。

  • 布尔值、Null 和 Undefined 被忽略

falsenullundefined 和 true 都是有效的子代,但它们不会直接被渲染。下面的表达式是等价的:

{false}
{null}
{undefined}
{true}

这在根据条件来确定是否渲染React元素时非常有用。以下的JSX只会在showHeadertrue时渲染

组件。

{showHeader &&
}

值得注意的是,JavaScript 中的一些 “falsy” 值(比如数字0),它们依然会被渲染。例如,下面的代码不会像你预期的那样运行,因为当 props.message 为空数组时,它会打印0:

{props.messages.length && }

要解决这个问题,请确保 && 前面的表达式始终为布尔值:

{props.messages.length > 0 && }

相反,如果你想让类似 falsetruenull 或 undefined 出现在输出中,你必须先把它转换成字符串 :

My JavaScript variable is {String(myVariable)}.
  • 限制单个子代

使用 PropTypes.element 你可以指定只传递一个子代

import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  render() {
    // This must be exactly one element or it will warn.
    const children = this.props.children;
    return (
      
{children}
); } } MyComponent.propTypes = { children: PropTypes.element.isRequired };

12.React 组件也可以通过数组的形式返回多个元素:

 

render() {
  // 不需要使用额外的元素包裹数组中的元素
  return [
    // 不要忘记 key :)
    
  • First item
  • ,
  • Second item
  • ,
  • Third item
  • , ]; }

     

    13.虚拟Dom的性能提升:

    • 在js中创建js对象(虚拟dom) 性能消耗是很低的,而创建dom需要调用底层webapplication的api,需要消耗更多性能。
    • 修改数据后更新dom:两个真实dom的比对是很耗性能,而通过js的虚拟dom进行比较就节约很多。

    缺陷版:

    【React】React之从基础到放弃_第8张图片

    优化版(react):

    【React】React之从基础到放弃_第9张图片

    原生应用通过解析虚拟dom创建出真实原生组件:例如android的layout->view。可以说虚拟dom是一个中间层(描述界面结构的对象),哪个端使用就解析渲染成哪个端的界面结构表示方法(浏览器:dom,android:window-view)

    14.diff算法(难点):优化新旧虚拟dom的比对

    diff:

    同层比对->有一层比对不同就将后面删除,直接渲染新的dom

    key值比对->dom对应关系确定,好复用

    15.setState设计成异步:为了减少虚拟dom的比对次数,周期性的将多次setState合并成一次setState,然后触发比对

    setState((prevState,props)=>{
          a:2
    },callBack);
    {
        a:1
    }
    
    + 合并
    {
        b:2
    }
    =>{
        a:1,
        b:2    
    }

    16.ref属性可以获得真实dom的节点,不建议直接使用ref操作dom。

    例:获得input标签

    【React】React之从基础到放弃_第10张图片

    何时使用 Refs

    下面是几个适合使用 refs 的情况:

    • 处理焦点、文本选择或媒体控制。
    • 触发强制动画。
    • 集成第三方 DOM 库

    如果可以通过声明式实现,则尽量避免使用 refs。

    注意

    如果 ref 回调以内联函数的方式定义,在更新期间它会被调用两次,第一次参数是 null ,之后参数是 DOM 元素。这是因为在每次渲染中都会创建一个新的函数实例。因此,React 需要清理旧的 ref 并且设置新的。通过将 ref 的回调函数定义成类的绑定函数的方式可以避免上述问题,但是大多数情况下无关紧要。

    原生方法获得真实dom

    const appRoot = document.getElementById('app-root');

    17.react生命周期

    【React】React之从基础到放弃_第11张图片

    componentWillReceiveProps():

    执行条件:

    • 子组件接收父组件参数
    • 父组件重新render

    【React】React之从基础到放弃_第12张图片

    shouldComponentUpdate(nextProps,nextState):可以用来避免父组件render后自动调用子组件render,但是子组件并没有数据变动

    18.实现组件间直接通信的context,而不需要使用props一级一级传递。redux的实现原理

    19.不需要使用额外父组件(div等)包裹的方法:Fragments

    React 中一个常见模式是为一个组件返回多个元素。Fragments 可以让你聚合一个子元素列表,并且不在DOM中增加额外节点。

    Fragments 看起来像空的 JSX 标签:<>是的语法糖。

    render() {
      return (
        <>
          
          
          
        
      );
    }

     20.将子组件渲染到父组件以外的地方:Portals

    ReactDOM.createPortal(child, container)
    

    第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或碎片。第二个参数(container)则是一个 DOM 元素。

     

    你可能感兴趣的:(react)