美文网首页
React 17 基础2

React 17 基础2

作者: 欢欣的膜笛 | 来源:发表于2021-01-18 00:32 被阅读0次

在 React 中设置焦点

class CustomTextInput extends React.Component {
  constructor(props) {
    super(props);
    // 创造一个 textInput DOM 元素的 ref
    this.textInput = React.createRef();
  }

  focus() {
    // 使用原始的 DOM API 显式地聚焦在 text input 上
    // 注意:我们通过访问 “current” 来获得 DOM 节点
    this.textInput.current.focus();
  }

  render() {
    // 使用 `ref` 回调函数以在实例的一个变量中存储文本输入 DOM 元素
    //(比如,this.textInput)。
    return (
      <input
        type="text"
        ref={this.textInput}
      />
    );
  }
}

有时,父组件需要把焦点设置在其子组件的一个元素上。我们可以通过在子组件上设置一个特殊的 prop 来对父组件暴露 DOM refs 从而把父组件的 ref 传向子节点的 DOM 节点。

function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} />
    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  render() {
    return (
      <CustomTextInput inputRef={this.inputElement} />
    );
  }
}

// 现在你就可以在需要时设置焦点了
this.inputElement.current.focus();

鼠标和指针事件

外部点击模式,用户可以通过点击元素以外的地方来关闭已打开的弹出框。
常规做法是组件加载时监听 window click 事件,卸载时移除,但是对于键盘切换会失效。故可以运用 onBlur 和 onFocus,实现这项功能。

class BlurExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.timeOutId = null;

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onBlurHandler = this.onBlurHandler.bind(this);
    this.onFocusHandler = this.onFocusHandler.bind(this);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  // 我们在下一个时间点使用 setTimeout 关闭弹窗。
  // 这是必要的,因为失去焦点事件会在新的焦点事件前被触发,
  // 我们需要通过这个步骤确认这个元素的一个子节点
  // 是否得到了焦点。
  onBlurHandler() {
    this.timeOutId = setTimeout(() => {
      this.setState({
        isOpen: false
      });
    });
  }

  // 如果一个子节点获得了焦点,不要关闭弹窗。
  onFocusHandler() {
    clearTimeout(this.timeOutId);
  }

  render() {
    // React 通过把失去焦点和获得焦点事件传输给父节点
    // 来帮助我们。
    return (
      <div onBlur={this.onBlurHandler}
           onFocus={this.onFocusHandler}>
        <button onClick={this.onClickHandler}
                aria-haspopup="true"
                aria-expanded={this.state.isOpen}>
          Select an option
        </button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}

语义化的 HTML

JSX 需要有一个根元素,有时为了不破坏语义化,可使用 Fragment 或者短语法

function ListItem({ item }) {
  return (
    <Fragment>
      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </Fragment>
  );
}

function ListItem({ item }) {
  return (
    <>
      <dt>{item.term}</dt>
      <dd>{item.description}</dd>
    </>
  );
}

React.lazy 组件懒加载

fallback 属性接受任何在组件加载过程中你想展示的 React 元素。你可以将 Suspense 组件置于懒加载组件之上的任何位置。你甚至可以用一个 Suspense组件包裹多个懒加载组件。

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

context

context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据,例如当前认证的用户、主题或首选语言。

// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
  render() {
    // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
    // 无论多深,任何组件都能读取这个值。
    // 在这个例子中,我们将 “dark” 作为当前的值传递下去。
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 指定 contextType 读取当前的 theme context。
  // React 会往上找到最近的 theme Provider,然后使用它的值。
  // 在这个例子中,当前的 theme 值为 “dark”。
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;
  }
}

相关文章

  • React 17 基础2

    在 React 中设置焦点 有时,父组件需要把焦点设置在其子组件的一个元素上。我们可以通过在子组件上设置一个特殊的...

  • 【React Native学习笔记二】React基础

    一、React JSX基础 1、React.js和React Native关系 2、React Native原理 ...

  • React 17 基础1

    简介 设计理念单向数据流、虚拟 DOM、组件化 组件化编程的思想React 以组件的方式去重新思考用户界面的构成,...

  • React

    (1)React环境搭建的过程 安装地址示例 (2)React 基础 (2.1) es6语法 (2.2) JSX ...

  • react冷门小知识 - 未完待续

    1. react合成事件 SyntheticEvent(React 17和老版本对比) React 17 以前 R...

  • React 16.4 快速上手

    第1章 React简介及基础语法 1-2 React开发环境搭建 cd /Users/XXX/Desktop/ho...

  • React Native与React的关系及特点

    一、React、React.js和React Native的关系 React是基础框架,是一套基础设计实现理念,开...

  • React 基础学习笔记

    React 基础学习笔记 黑马程序员视频:传送门 1. React 基础 1.1 介绍react React起源于...

  • React面试题 整理脑图

    react基础 React生命周期 react-router react进阶 react Hooks redux 其他

  • 2、react基础介绍

    React理念 划分组件边界的原则 React组件的数据种类 React组件的声明周期 组件的划分 高内聚 低耦合...

网友评论

      本文标题:React 17 基础2

      本文链接:https://www.haomeiwen.com/subject/cudxzktx.html