Got the idea form this lesson. Not sure whether it is the ncessary, no othere better way to handle it.

Have a TodoList component, every time types in NewTodo input fields, will trigger the re-rendering for all components.

  1. import React, { useState, useContext, useCallback } from "react";
  2. import NewTodo from "./NewTodo";
  3. import TodoItem from "./TodoItem5";
  4. import { Container, List } from "./Styled";
  5. import About from "./About";
  6. import { useTodosWithLocalStorage, useKeyDown } from "./hooks";
  7. import { useTitle as useDocumentTitle } from "react-use";
  8. import ThemeContext from "./ThemeContext";
  9.  
  10. const incompleteTodoCount = todos =>
  11. todos.reduce((memo, todo) => (!todo.completed ? memo + 1 : memo), 0);
  12.  
  13. export default function TodoList() {
  14. const [newTodo, updateNewTodo] = useState("");
  15. const [todos, dispatch] = useTodosWithLocalStorage([]);
  16. const inCompleteCount = incompleteTodoCount(todos);
  17. const title = inCompleteCount ? `Todos (${inCompleteCount})` : "Todos";
  18. useDocumentTitle(title);
  19. let [showAbout, setShowAbout] = useKeyDown(
  20. { "?": true, Escape: false },
  21. false
  22. );
  23. const handleNewSubmit = e => {
  24. e.preventDefault();
  25. dispatch({ type: "ADD_TODO", text: newTodo });
  26. updateNewTodo("");
  27. };
  28. const theme = useContext(ThemeContext);
  29.  
  30. return (
  31. <Container todos={todos}>
  32. <NewTodo
  33. onSubmit={handleNewSubmit}
  34. value={newTodo}
  35. onChange={e => updateNewTodo(e.target.value)}
  36. />
  37. {!!todos.length && (
  38. <List theme={theme}>
  39. {todos.map(todo => (
  40. <TodoItem
  41. key={todo.id}
  42. todo={todo}
  43. onChange={id => dispatch({ type: "TOGGLE_TODO", id })}
  44. onDelete={id => dispatch({ type: "DELETE_TODO", id })}
  45. />
  46. ))}
  47. </List>
  48. )}
  49. <About isOpen={showAbout} onClose={() => setShowAbout(false)} />
  50. </Container>
  51. );
  52. }

The way to solve the problem is

1. For every callback:

  1. <TodoItem
  2. onChange={id => dispatch({ type: "TOGGLE_TODO", id })}
  3. onDelete={id => dispatch({ type: "DELETE_TODO", id })}
  4. />
  5.  
  6. <About isOpen={showAbout} onClose={() => setShowAbout(false)} />

We should replace with useCallback hooks:

  1. const handleChange = useCallback(
  2. id => dispatch({ type: "TOGGLE_TODO", id }),
  3. []
  4. );
  5. const handleDelete = useCallback(
  6. id => dispatch({ type: "DELETE_TODO", id }),
  7. []
  8. );
  9.  
  10. const handleClose = userCallback(
  11. () => setShowAbout(false), []
  12. )
  1. {!!todos.length && (
  2. <List theme={theme}>
  3. {todos.map(todo => (
  4. <TodoItem
  5. key={todo.id}
  6. todo={todo}
  7. onChange={handleChange}
  8. onDelete={handleDelete}
  9. />
  10. ))}
  11. </List>
  12. )}
  13. <About isOpen={showAbout} onClose={handleClose} />

This helps to reduce some extra re-rendering.

2. Using Reac.memo for function component:

  1. import React, { useContext } from "react";
  2. import Checkbox from "./Checkbox";
  3. import ThemeContext from "./ThemeContext";
  4. import { Button, Item } from "./Styled";
  5.  
  6. const TodoItem = React.memo(({ todo, onChange, onDelete }) => {
  7. console.log("TodoItem5", { todo, onChange, onDelete });
  8. const theme = useContext(ThemeContext);
  9. return (
  10. <Item key={todo.id} theme={theme}>
  11. <Checkbox
  12. id={todo.id}
  13. label={todo.text}
  14. checked={todo.completed}
  15. onChange={onChange.bind(this, todo.id)}
  16. />
  17. <Button onClick={onDelete.bind(this, todo.id)} theme={theme}>
  18. x
  19. </Button>
  20. </Item>
  21. );
  22. });
  23.  
  24. export default TodoItem;
  1. import React from "react";
  2. import styled from "react-emotion";
  3.  
  4. import { Dialog } from "@reach/dialog";
  5.  
  6. ...
  7.  
  8. export default React.memo(function TodoItem({ isOpen, onClose }) {
  9. return (
  10. <Dialog isOpen={isOpen}>
  11. ...
  12. </Dialog>
  13. );
  14. });

Assume that every times I should wrap function component with React.memo() and use useCallback whenever necessary.

[React] Preventing extra re-rendering with function component by using React.memo and useCallback的更多相关文章

  1. [React] Write a stateful Component with the React useState Hook and TypeScript

    Here we refactor a React TypeScript class component to a function component with a useState hook and ...

  2. 精读《Function Component 入门》

    1. 引言 如果你在使用 React 16,可以尝试 Function Component 风格,享受更大的灵活性.但在尝试之前,最好先阅读本文,对 Function Component 的思维模式有 ...

  3. [React] Preview and edit a component live with React Live

    In this lesson we'll use React Live to preview and edit a component directly in the browser. React L ...

  4. [React] Forward a DOM reference to another Component using forwardRef in React 16.3

    The function forwardRef allows us to extract a ref and pass it to its descendants. This is a powerfu ...

  5. 3.React Native在Android中自己定义Component和Module

    React Native终于展示的UI全是Native的UI.将Native的信息封装成React方便的调用. 那么Native是怎样封装成React调用的?Native和React是怎样交互的? V ...

  6. React报错之React Hook 'useEffect' is called in function

    正文从这开始~ 总览 为了解决错误"React Hook 'useEffect' is called in function that is neither a React function ...

  7. [React & Debug] Quick way to debug Stateless component

    For example we have the following code: const TodoList = (props) => ( <div className="Tod ...

  8. react 使用react-router-dom 在Route对象上component 参数接收的是一个方法而非一个对象

    其实对于jsx语法 一直觉的它有点清晰都不是很好,js和html混在一起有点不伦不类的样子,以下是我在使用react中遇到的一个很奇葩的事情 假定你定义了一个component Mine import ...

  9. 《React Native 精解与实战》书籍连载「React Native 底层原理」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

随机推荐

  1. SCU 4441 Necklace

    最长上升子序列,枚举. 因为$10000$最多只有$10$个,所以可以枚举采用哪一个$10000$,因为是一个环,所以每次枚举到一个$10000$,可以把这个移到最后,然后算从前往后的$LIS$和从后 ...

  2. Redis学习篇(四)之List类型及其操作

    Redis的List是一个双向链表 LPUSH 作用:向列表左端添加元素 语法:LPUSH key value value... 从左到右逐个添加到左端,前面的先添加, 可以一次添加多个元素 RPUS ...

  3. 【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)

    4568: [Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形 ...

  4. 比较IBM MQSeries和BEA WebLogic JMS Server(转载)

    在面向消息的中间件(MOM)这个领域,IBM MQSeries (又称WebSphere MQ)一直是当仁不让的超级大哥,其它还有一些小兄弟,比如SwiftMQ.SonicMQ之类.但近年来随着J2E ...

  5. CSS 笔记——导航栏、下拉菜单、提示工具

    8. 导航栏.下拉菜单.提示工具 (1)导航栏 垂直导航栏 <!DOCTYPE html> <html lang="en"> <head> &l ...

  6. 在MySQL字段中使用逗号分隔符

    大多数开发者应该都遇到过在mysql字段中存储逗号分割字符串的经历,无论这些被分割的字段代表的是id还是tag,这个字段都应该具有如下几个共性. 被分割的字段一定是有限而且数量较少的,我们不可能在一个 ...

  7. Spring Boot中Request method 'PUT' not supported

    在项目中使用restful风格put提交时报错,是由于form表单中的th:href引起的(支持post提交),改为th:action即可

  8. Problem C: 深入浅出学算法004-求多个数的最小公倍数

    Description 求n个整数的最小公倍数 Input 多组测试数据,先输入整数T表示组数 然后每行先输入1个整数n,后面输入n个整数k1 k2...kn Output 求k1 k2 ...kn的 ...

  9. bzoj 2938

    收获: 1.AC自动机可以在建立fail时将一些不存在的儿子指针指向对应的位置. 2.判断环时不要想当然地写个这样的版本: bool dfs( int u ) { if( vis[u] ) retur ...

  10. request.getScheme() 取到https正确的协议(转载)

    最近在做一个项目, 架构上使用了 Nginx +tomcat 集群, 且nginx下配置了SSL,tomcat no SSL,项目使用https协议 但是,明明是https url请求,发现 log里 ...