美文网首页前端开发让前端飞React.js
React学习系列之 React Hooks

React学习系列之 React Hooks

作者: 寒雨心亭 | 来源:发表于2019-05-07 15:44 被阅读3次

React Hooks

React 16.8、useState、

React 16.8.0 is the first release to support Hooks. When upgrading, don’t forget to update all packages, including React DOM. React Native will support Hooks in the next stable release.

why ?

  • It’s hard to reuse stateful logic between components:

render props、higher-order components: restructure your components

With Hooks, you can extract stateful logic from a component so it can be tested independently and reused.

Hooks allow you to reuse stateful logic without changing your component hierarchy.

Hooks let you split one component into smaller functions based on what pieces are related (such as setting up a subscription or fetching data),

  • Classes confuse both people and machines

Hooks let you use more of React’s features without classes.

React components have always been closer to functions.

Hooks embrace functions, but without sacrificing the practical spirit of React.

how to do?

  • Hooks work side-by-side with existing code so you can adopt them gradually.

  • we will keep supporting class components for the foreseeable future.

  • 新组件就用hooks吧,老的class 组件也没有必要重新写,backwards-compatible。

Hooks 概览

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

State Hook

初识


//  We import the useState Hook from React. It lets us keep local state in a function component.

import React, { useState } from 'react';

function Example() {

  // Declare a new state variable, which we'll call "count"

  const [count, setCount] = useState(0);

/* // 数组解构

var fruitStateVariable = useState('banana'); // Returns a pair

  var fruit = fruitStateVariable[0]; // First item in a pair

  var setFruit = fruitStateVariable[1]; // Second item in a pair

*/

  return (

    <div>

      <p>You clicked {count} times</p>

//  When the user clicks, we call setCount with a new value. React will then re-render the Example component, passing the new count value to it.

      <button onClick={() => setCount(count + 1)}>

        Click me

      </button>

    </div>

  );

}

useState is a Hook;

useState returns a pair: the current state value and a function that lets you update it.


function ExampleWithManyStates() {

  // Declare multiple state variables!

  const [age, setAge] = useState(42);

  const [fruit, setFruit] = useState('banana');

  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);

  // ...

}

进阶

等价的 Class 例子

class Example extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      count: 0

    };

  }

  render() {

    return (

      <div>

        <p>You clicked {this.state.count} times</p>

        <button onClick={() => this.setState({ count: this.state.count + 1 })}>

          Click me

        </button>

      </div>

    );

  }

}

Hooks and Function Components

// function components

const Example = (props) => {

  // You can use Hooks here!

  return <div />;

}

// or

function Example(props) {

  // You can use Hooks here!

  return <div />;

}

Hooks don’t work inside classes. But you can use them instead of writing classes.

What’s a Hook?

A Hook is a special function that lets you “hook into” React features.

e.g. : useState is a Hook that lets you add React state to function components.

If you write a function component and realize you need to add some state to it, previously you had to convert it to a class.

Now you can use a Hook inside the existing function component.

Declaring a State Variable

// in class components

class Example extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      count: 0

    };

  }

// useState in hooks, in a function components

// In a function component, we have no this, so we can’t assign or read this.state. Instead, we call the useState Hook directly inside our component

// The only argument to the useState() Hook is the initial state.

// If we wanted to store two different values in state, we would call useState() twice.

// useState returns a pair of values: the current state and a function that updates it.

import React, { useState } from 'react';

function Example() {

  // Declare a new state variable, which we'll call "count"

  const [count, setCount] = useState(0);

Reading State

// in a class

<p>You clicked {this.state.count} times</p>

// in a function

<p>You clicked {count} times</p>

Updating State

// in a class

<button onClick={() => this.setState({ count: this.state.count + 1 })}>

    Click me

  </button>

// in a function

<button onClick={() => setCount(count + 1)}>

    Click me

  </button>

Effect Hook

useEffect,adds the ability to perform side effects from a function component.

It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API.

Effects are declared inside the component so they have access to its props and state.


import React, { useState, useEffect } from 'react';

function Example() {

  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:

  useEffect(() => {

    // Update the document title using the browser API

    document.title = `You clicked ${count} times`;

  });

  return (

    <div>

      <p>You clicked {count} times</p>

      <button onClick={() => setCount(count + 1)}>

        Click me

      </button>

    </div>

  );

}

Effects may also optionally specify how to “clean up” after them by returning a function.


import React, { useState, useEffect } from 'react';

function FriendStatus(props) {

  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {

    setIsOnline(status.isOnline);

  }

  useEffect(() => {

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);

    return () => {

      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);

    };

  });

  if (isOnline === null) {

    return 'Loading...';

  }

  return isOnline ? 'Online' : 'Offline';

}

多个effect 时,


function FriendStatusWithCounter(props) {

  const [count, setCount] = useState(0);

  useEffect(() => {

    document.title = `You clicked ${count} times`;

  });

  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);

    return () => {

      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);

    };

  });

  function handleStatusChange(status) {

    setIsOnline(status.isOnline);

  }

  // ...

Hooks 规则

Hooks are JavaScript functions, but they impose two additional rules:

  • Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.

  • Only call Hooks from React function components. Don’t call Hooks from regular JavaScript functions.

一个插件:linter plugin

创建自己的Hooks


import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {

  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {

    setIsOnline(status.isOnline);

  }

  useEffect(() => {

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);

    return () => {

      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);

    };

  });

  return isOnline;

}

// component 1

function FriendStatus(props) {

  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {

    return 'Loading...';

  }

  return isOnline ? 'Online' : 'Offline';

}

// component 2

function FriendListItem(props) {

  const isOnline = useFriendStatus(props.friend.id);

  return (

    <li style={{ color: isOnline ? 'green' : 'black' }}>

      {props.friend.name}

    </li>

  );

}

Hooks 约定俗成的一些东西:

Custom Hooks are more of a convention than a feature.

If a function’s name starts with ”use” and it calls other Hooks, we say it is a custom Hook.

The useSomething naming convention is how our linter plugin is able to find bugs in the code using Hooks.

其他的Hooks-Hooks API

a few less commonly used built-in Hooks that you might find useful.

如:useContext lets you subscribe to React context without introducing nesting。


function Example() {

  const locale = useContext(LocaleContext);

  const theme = useContext(ThemeContext);

  // ...

}

useReducer lets you manage local state of complex components with a reducer:


function Todos() {

  const [todos, dispatch] = useReducer(todosReducer);

  // ...

相关文章

  • react-hooks

    前置 学习面试视频 总结react hooks react-hooks react-hooks为函数组件提供了一些...

  • React学习系列之 React Hooks

    React Hooks React 16.8、useState、 React 16.8.0 is the firs...

  • 十个案例学会 React Hooks

    在学会使用React Hooks之前,可以先看一下相关原理学习React Hooks 前言 在 React 的世界...

  • React Hooks

    React Hooks Hooks其实就是有状态的函数式组件。 React Hooks让React的成本降低了很多...

  • React Hooks

    前言 React Conf 2018 上 React 提出了关于 React Hooks 的提案,Hooks 作为...

  • react-hooks

    react-hooks react-hooks 是react16.8以后,react新增的钩子API,目的是增加代...

  • React Hooks的入门简介

    什么是React Hooks? 首先React Hooks是React生态圈里的新特性,它改变了传统react的开...

  • React Hooks 入门

    React Hooks 是 React v16.8 版本引入了全新的 API。 React Hooks 基本概念 ...

  • react hooks 源码分析 --- useState

    1. react hooks简介 react hooks 是react 16.8.0 的新增特性,它可以让你在不编...

  • React hooks(钩子)

    React hooks(钩子) React hooks 是React 16.8中的新增功能。它们使您无需编写类即可...

网友评论

    本文标题:React学习系列之 React Hooks

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