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.

import React, { useState, useContext, useCallback } from "react";
import NewTodo from "./NewTodo";
import TodoItem from "./TodoItem5";
import { Container, List } from "./Styled";
import About from "./About";
import { useTodosWithLocalStorage, useKeyDown } from "./hooks";
import { useTitle as useDocumentTitle } from "react-use";
import ThemeContext from "./ThemeContext"; const incompleteTodoCount = todos =>
todos.reduce((memo, todo) => (!todo.completed ? memo + 1 : memo), 0); export default function TodoList() {
const [newTodo, updateNewTodo] = useState("");
const [todos, dispatch] = useTodosWithLocalStorage([]);
const inCompleteCount = incompleteTodoCount(todos);
const title = inCompleteCount ? `Todos (${inCompleteCount})` : "Todos";
useDocumentTitle(title);
let [showAbout, setShowAbout] = useKeyDown(
{ "?": true, Escape: false },
false
);
const handleNewSubmit = e => {
e.preventDefault();
dispatch({ type: "ADD_TODO", text: newTodo });
updateNewTodo("");
};
const theme = useContext(ThemeContext); return (
<Container todos={todos}>
<NewTodo
onSubmit={handleNewSubmit}
value={newTodo}
onChange={e => updateNewTodo(e.target.value)}
/>
{!!todos.length && (
<List theme={theme}>
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onChange={id => dispatch({ type: "TOGGLE_TODO", id })}
onDelete={id => dispatch({ type: "DELETE_TODO", id })}
/>
))}
</List>
)}
<About isOpen={showAbout} onClose={() => setShowAbout(false)} />
</Container>
);
}

The way to solve the problem is

1. For every callback:

<TodoItem
onChange={id => dispatch({ type: "TOGGLE_TODO", id })}
onDelete={id => dispatch({ type: "DELETE_TODO", id })}
/> <About isOpen={showAbout} onClose={() => setShowAbout(false)} />

We should replace with useCallback hooks:

  const handleChange = useCallback(
id => dispatch({ type: "TOGGLE_TODO", id }),
[]
);
const handleDelete = useCallback(
id => dispatch({ type: "DELETE_TODO", id }),
[]
); const handleClose = userCallback(
() => setShowAbout(false), []
)
      {!!todos.length && (
<List theme={theme}>
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
onChange={handleChange}
onDelete={handleDelete}
/>
))}
</List>
)}
<About isOpen={showAbout} onClose={handleClose} />

This helps to reduce some extra re-rendering.

2. Using Reac.memo for function component:

import React, { useContext } from "react";
import Checkbox from "./Checkbox";
import ThemeContext from "./ThemeContext";
import { Button, Item } from "./Styled"; const TodoItem = React.memo(({ todo, onChange, onDelete }) => {
console.log("TodoItem5", { todo, onChange, onDelete });
const theme = useContext(ThemeContext);
return (
<Item key={todo.id} theme={theme}>
<Checkbox
id={todo.id}
label={todo.text}
checked={todo.completed}
onChange={onChange.bind(this, todo.id)}
/>
<Button onClick={onDelete.bind(this, todo.id)} theme={theme}>
x
</Button>
</Item>
);
}); export default TodoItem;
import React from "react";
import styled from "react-emotion"; import { Dialog } from "@reach/dialog"; ... export default React.memo(function TodoItem({ isOpen, onClose }) {
return (
<Dialog isOpen={isOpen}>
...
</Dialog>
);
});

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. js中箭头函数和普通函数this的区别

    最近在学习angularJs的时候由于里面涉及到了箭头函数,箭头函数除了声明上有点区别以外,和普通函数最主要的区别还是在this的问题上. Js中函数中嵌套的函数this不会 “继承”.比如说以下代码 ...

  2. 【面试总结-编程】多行两列数据,实现同key的value求和并输出

    一个文件,两列,多行. 第一列是字母,第二列是数字,同列数据之间通过空格分割. 统计首列字母相同的第二列之和. 样例输入: A 5 B 6 OO 7 A 6 A 2 OO 2 输出: A:13 B:6 ...

  3. linux常用解压命令总结

    .xz 解压: tar xvf FileName.tar.xz 打包: tar cvf FileName.tar DirName .tar 解包:tar xvf FileName.tar 打包:tar ...

  4. JavaScript初步

    隐式转换 其他类型转换成布尔类型: undefined --> false null --> false 0或者0.0或者NaN --> false 字符串长度为0 --> f ...

  5. shell中的条件判断if和测试

    (一)条件判断 if 中-z 到 -d 的意思 [ -a file ] 若file存在,则为真. [ -b file ] 若file存在且是一个块特殊文件,则为真. [ -c file ] 若file ...

  6. HDU 1698 Just a Hook (线段树)

    Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...

  7. [BZOJ4373]算术天才⑨与等差数列(线段树)

    [l,r]中所有数排序后能构成公差为k的等差数列,当且仅当: 1.区间中最大数-最小数=k*(r-l) 2.k能整除区间中任意两个相邻数之差,即k | gcd(a[l+1]-a[l],a[l+2]-a ...

  8. 普通免费QQ客服在PC、手机端解决方案

    注意:以下测试 浏览器在Chrome,手机在iphone6 营销QQ.企业QQ(http://b.qq.com/)跟普通免费QQ(http://shang.qq.com/v3/widget.html) ...

  9. mysql select语句执行顺序

        SELECT语句定义       一个完成的SELECT语句包含可选的几个子句. SELECT语句的定义如下: <SELECT clause> [<FROM clause&g ...

  10. win7 系统装SQLServer2000 成功

    昨天在win7上装SQLServer数据库,写一下体会.首先,如果以前安装的话,要删除干净.我也找了半天的网络资料.1.把原来SQLServer的安装目录 C:\Program Files\Micro ...