From e1952027a961b3233ddbee991cfb9372c56e29b6 Mon Sep 17 00:00:00 2001 From: fer Date: Mon, 15 Apr 2019 08:22:22 +0800 Subject: [PATCH 1/4] doc: update content 1. add three newly questions (302-304) 2. sync for README-en.md --- README-en.md | 93 ++++++++++++++-------------- README.md | 168 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 157 insertions(+), 104 deletions(-) diff --git a/README-en.md b/README-en.md index 305770b..a4e125b 100755 --- a/README-en.md +++ b/README-en.md @@ -315,16 +315,15 @@ |299| [How to add a bootstrap for a react application?](#how-to-add-a-bootstrap-for-a-react-application)| |300| [Can you list down top websites or applications using react as front end framework?](#can-you-list-down-top-websites-or-applications-using-react-as-front-end-framework)| |301| [Is it recommended to use CSS In JS technique in React?](#is-it-recommended-to-use-css-in-js-technique-in-react)| +|302| [Do I need to rewrite all my class components with hooks?](#do-i-need-to-rewrite-all-my-class-components-with-hooks)| +|303| [How to fetch data with React Hooks?](#how-to-fetch-data-with-react-hooks)| +|304| [Is Hooks cover all use cases for classes?](#is-hooks-cover-all-use-cases-for-classes)| ## Core React 1. ### What is React? React is an **open-source frontend JavaScript library** which is used for building user interfaces especially for single page applications. It is used for handling view layer for web and mobile apps. React was created by Jordan Walke, a software engineer working for Facebook. React was first deployed on Facebook's News Feed in 2011 and on Instagram in 2012. - - React 是一个开源的前端 JavaScript 框架,可用于构建用户界面特别是单页应用程序。它被用于作为网页和移动应用的视图层。React 由 Facebook - 的工程师 Jordan Walke 创建。在 2011 年 React 应用首次被部署到 Facebook 的信息流上,之后于 2012 年被应用到 Instagram 中。 - 2. ### What are the major features of React? @@ -335,12 +334,6 @@ * Follows *Unidirectional** data flow or data binding. * Uses **reusable/composable** UI components to develop the view. - React 的主要特性有: - * 考虑到真实的 DOM 操作比较昂贵,它使用 VirtualDOM 来替代真实的 DOM - * 支持服务端渲染 - * 遵从单向数据流或数据绑定 - * 使用可重用/可组合的 UI 组件开发视图 - 3. ### What is JSX? *JSX* is a XML-like syntax extension to ECMAScript (the acronym stands for *JavaScript XML*). Basically it just provides syntactic sugar for the `React.createElement()` function, giving us expressiveness of JavaScript along with HTML like template syntax. @@ -358,31 +351,11 @@ } } ``` - JSX 是一个对 ECMAScript 进行类 XML 的语法的扩展。它只是为 `React.createElement()` 函数提供语法糖,从而让在我们在 JavaScript 中, - 使用类 HTML 模板的语法,进行页面描述。 - - 在以下示例中,在 `

` 标签中的文本会以 JavaScript 函数的形式返回给渲染函数。 - - ```jsx harmony - class App extends React.Component { - render() { - return( -
-

{'Welcome to React world!'}

-
- ) - } - } - ``` - 4. ### What is the difference between Element and Component? An *Element* is a plain object describing what you want to appear on the screen in terms of the DOM nodes or other components. *Elements* can contain other *Elements* in their props. Creating a React element is cheap. Once an element is created, it is never mutated. - 一个 Element 是一个普通的对象,以 DOM 节点或其他组件的方式描述你期望在屏幕上呈现的内容。 - - React 元素的对象表示如下: The object representation of React Element would be as follows: ```javascript @@ -394,7 +367,6 @@ ``` The above `React.createElement()` function returns an object: - 上面的 `React.createElement()` 函数会返回一个对象。 ``` { @@ -407,25 +379,19 @@ ``` And finally it renders to the DOM using `ReactDOM.render()`: - 最终使用 `ReactDOM.render()` 方法渲染到 DOM: ```html
Login
``` - Whereas a **component** can be declared in several different ways. It can be a class with a `render()` method. Alternatively, in simple cases, it can be defined as a function. In either case, it takes props as an input, and returns an JSX tree as the output: - - 然而一个组件可以以多种不同方式进行声明。它可以是一个含有 `render()` 方法的类。在简单的场景中,它能被定义成函数。在其它场景,它接收 props - 作为输入,返回 JSX 树作为输出: + Whereas a **component** can be declared in several different ways. It can be a class with a `render()` method. Alternatively, in simple cases, it can be defined as a function. In either case, it takes props as an input, and returns a JSX tree as the output: ```javascript const Button = ({ onLogin }) =>
``` - Then JSX gets transpiled to `React.createElement()` function tree: - - 接着 JSX 被转译为 `React.createElement()` 函数树: + Then JSX gets transpiled to a `React.createElement()` function tree: ```javascript const Button = ({ onLogin }) => React.createElement( @@ -438,15 +404,12 @@ 5. ### How to create components in React? There are two possible ways to create a component. - 这里有两种可行方式来创建一个组件: 1. **Function Components:** This is the simplest way to create a component. Those are pure JavaScript functions that accept props object as first parameter and return React elements: - 1. **Function Components:** 这是创建组件最简单的方式 - ```jsx harmony function Greeting({ message }) { - return

{`Hello, ${message}`}

+ return

{`Hello, ${message}`}


 } ``` @@ -1109,7 +1072,7 @@ 45. ### Why React uses `className` over `class` attribute? - `class` is a keyword in JavaSript, and JSX is an extension of JavaScript. That's the principal reason why React uses `className` instead of `class`. Pass a string as the `className` prop. + `class` is a keyword in JavaScript, and JSX is an extension of JavaScript. That's the principal reason why React uses `className` instead of `class`. Pass a string as the `className` prop. ```jsx harmony render() { @@ -3879,6 +3842,7 @@ 217. ### What are HOC factory implementations? There are two main ways of implementing HOCs in React. 1. Props Proxy (PP) and 2. Inheritance Inversion (II). They follow different approaches for manipulating the *WrappedComponent*. + **Props Proxy** In this approach, the render method of the HOC returns a React Element of the type of the WrappedComponent. We also pass through the props that the HOC receives, hence the name **Props Proxy**. @@ -3894,6 +3858,7 @@ } ``` **Inheritance Inversion** + In this approach, the returned HOC class (Enhancer) extends the WrappedComponent. It is called Inheritance Inversion because instead of the WrappedComponent extending some Enhancer class, it is passively extended by the Enhancer. In this way the relationship between them seems **inverse**. ```jsx @@ -4173,7 +4138,7 @@ The render() method is the only required method in a class component. i.e, All methods other than render method are optional for a class component. 239. ### What are the possible return types of render method? Below are the list of following types used and return from render method, - 1. **React elements:** Elements that instruct React to render a DOM node. It includes html elements such as
and user defined elements. + 1. **React elements:** Elements that instruct React to render a DOM node. It includes html elements such as `
` and user defined elements. 2. **Arrays and fragments:** Return multiple elements to render as Arrays and Fragments to wrap multiple elements 3. **Portals:** Render children into a different DOM subtree. 4. **String and numbers:** Render both Strings and Numbers as text nodes in the DOM @@ -5064,4 +5029,40 @@ 9. Netflix 10. PayPal 301. ### Is it recommended to use CSS In JS technique in React? - React does not have any opinion about how styles are defined but if you are a beginner then good starting point is to define your styles in a separate *.css file as usual and refer to them using className. This functionality is not part of React but came from third-party libraries. But If you want to try a different approach(CSS-In-JS) then styled-components library is a good option. \ No newline at end of file + React does not have any opinion about how styles are defined but if you are a beginner then good starting point is to define your styles in a separate *.css file as usual and refer to them using className. This functionality is not part of React but came from third-party libraries. But If you want to try a different approach(CSS-In-JS) then styled-components library is a good option. +302. ### Do I need to rewrite all my class components with hooks? + No. But you can try Hooks in a few components(or new components) without rewriting any existing code. Because there are no plans to remove classes in ReactJS. +303. ### How to fetch data with React Hooks? + The effect hook called `useEffect` is used to fetch the data with axios from the API and to set the data in the local state of the component with the state hook’s update function. + Let's take an example in which it fetches list of react articles from the API + ```javascript + import React, { useState, useEffect } from 'react'; + import axios from 'axios'; + + function App() { + const [data, setData] = useState({ hits: [] }); + + useEffect(async () => { + const result = await axios( + 'http://hn.algolia.com/api/v1/search?query=react', + ); + + setData(result.data); + }, []); + + return ( + + ); + } + + export default App; + ``` + Remember we provided an empty array as second argument to the effect hook to avoid activating it on component updates but only for the mounting of the component. i.e, It fetches only for component mount. +304. ### Is Hooks cover all use cases for classes? + Hooks doesn't cover all use cases of classes but there is a plan to add them soon. Currently there are no Hook equivalents to the uncommon **getSnapshotBeforeUpdate** and **componentDidCatch** lifecycles yet. diff --git a/README.md b/README.md index e9c70e8..62bd790 100755 --- a/README.md +++ b/README.md @@ -322,6 +322,9 @@ |299 | [如何为 React 应用程序添加 bootstrap?](#如何为-react-应用程序添加-bootstrap) | |300 | [你能否列出使用 React 作为前端框架的顶级网站或应用程序?](#你能否列出使用-react-作为前端框架的顶级网站或应用程序) | |301 | [是否建议在 React 中使用 CSS In JS 技术?](#是否建议在-react-中使用-css-in-js-技术) | +|302 | [我需要用 hooks 重写所有类组件吗?](#我需要用-hooks-重写所有类组件吗) | +|303 | [如何使用 React Hooks 获取数据?](#如何使用-react-hooks-获取数据) | +|304 | [Hooks 是否涵盖了类的所有用例?](#hooks-是否涵盖了类的所有用例) | ## Core React @@ -1679,7 +1682,7 @@ } } ``` - + **[⬆ 返回顶部](#目录)** 67. ### 如何有条件地渲染组件? @@ -2450,7 +2453,7 @@ React.render(, document.getElementById('container')) ``` - + **[⬆ 返回顶部](#目录)** 106. ### 为什么你不能更新 React 中的 props? @@ -4350,7 +4353,7 @@
) ``` - + **[⬆ 返回顶部](#目录)** 215. ### 为什么不建议使用内联引用回调或函数? @@ -4362,7 +4365,7 @@ handleSubmit = () => { console.log("Input Value is: ", this.input.value) } - + render () { return (
@@ -4375,19 +4378,19 @@ } } ``` - + 但我们期望的是当组件挂载时,ref 回调只会被调用一次。一个快速修复的方法是使用 ES7 类属性语法定义函数。 - + ```jsx class UserForm extends Component { handleSubmit = () => { console.log("Input Value is: ", this.input.value) } - + setSearchInput = (input) => { this.input = input } - + render () { return ( @@ -4417,7 +4420,7 @@ 在这种方法中,HOC 的 render 方法返回 WrappedComponent 类型的 React 元素。我们通过 HOC 收到 props,因此定义为**属性代理**。 ```jsx - + function ppHOC(WrappedComponent) { return class PP extends React.Component { render() { @@ -4473,7 +4476,7 @@ import ReactDOM from 'react-dom'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; - + ReactDOM.render(, document.getElementById('root')); registerServiceWorker(); ``` @@ -4498,7 +4501,7 @@ ```jsx const OtherComponent = React.lazy(() => import('./OtherComponent')); - + function MyComponent() { return (
@@ -4582,24 +4585,24 @@ ```jsx class Counter extends Component { state = { value: 0 }; - + handleIncrement = () => { this.setState(prevState => ({ value: prevState.value + 1 })); }; - + handleDecrement = () => { this.setState(prevState => ({ value: prevState.value - 1 })); }; - + render() { return (
{this.state.value} - +
@@ -4616,11 +4619,11 @@ ```jsx import { useState } from 'react'; - + function Example() { // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); - + return (

You clicked {count} times

@@ -4633,7 +4636,7 @@ ``` 阅读资源: - + 1. [掘金 - 30分钟精通React Hooks](https://juejin.im/post/5be3ea136fb9a049f9121014) **[⬆ 返回顶部](#目录)** @@ -4737,7 +4740,7 @@ super(props); this.state = { error: null }; } - + handleClick = () => { try { // Do something that could throw @@ -4745,7 +4748,7 @@ this.setState({ error }); } } - + render() { if (this.state.error) { return

Caught an error.

@@ -4860,11 +4863,11 @@ class MyButton extends React.Component { // ... } - + MyButton.defaultProps = { color: 'red' }; - + ``` 如果未设置 props.color,则会使用默认值 `red`。 也就是说,每当你试图访问 color 属性时,它都使用默认值。 @@ -4901,18 +4904,18 @@ super(props); this.state = { hasError: false }; } - + static getDerivedStateFromError(error) { // Update state so the next render will show the fallback UI. return { hasError: true }; } - + render() { if (this.state.hasError) { // You can render any custom fallback UI return

Something went wrong.

; } - + return this.props.children; } } @@ -4944,7 +4947,7 @@ 247. ### displayName 类属性的用途是什么? displayName 被用于调试信息。通常,你不需要显式设置它,因为它是从定义组件的函数或类的名称推断出来的。如果出于调试目的或在创建高阶组件时显示不同的名称,可能需要显式设置它。 - + 例如,若要简化调试,请选择一个显示名称,以表明它是 withSubscription HOC 的结果。 ```javascript @@ -4953,7 +4956,7 @@ WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`; return WithSubscription; } - + function getDisplayName(WrappedComponent) { return WrappedComponent.displayName || WrappedComponent.name || 'Component'; } @@ -4984,13 +4987,13 @@ **moduleA.js** ```javascript const moduleA = 'Hello'; - + export { moduleA }; ``` **App.js** ```javascript import React, { Component } from 'react'; - + class App extends Component { handleClick = () => { import('./moduleA') @@ -5001,7 +5004,7 @@ // Handle failure }); }; - + render() { return (
@@ -5010,7 +5013,7 @@ ); } } - + export default App; ``` @@ -5134,16 +5137,16 @@ class LogProps extends React.Component { // ... } - + function forwardRef(props, ref) { return ; } - + // Give this component a more helpful display name in DevTools. // e.g. "ForwardRef(logProps(MyComponent))" const name = Component.displayName || Component.name; forwardRef.displayName = `logProps(${name})`; - + return React.forwardRef(forwardRef); } ``` @@ -5156,7 +5159,7 @@ ```javascript - + ``` @@ -5209,7 +5212,7 @@ 260. ### 如何防止函数被多次调用? 如果你使用一个事件处理程序,如 **onClick or onScroll** 并希望防止回调被过快地触发,那么你可以限制回调的执行速度。 - + 这可以通过以下可能的方式实现: 1. **Throttling:** 基于时间的频率进行更改。例如,它可以使用 lodash 的 _.throttle 函数。 @@ -5247,7 +5250,7 @@ ); ReactDOM.render(element, document.getElementById('root')); } - + setInterval(tick, 1000); ``` @@ -5290,7 +5293,7 @@ posts: response.posts }); }); - + fetchComments().then(response => { this.setState({ comments: response.comments @@ -5325,7 +5328,7 @@ if (!props.loggedIn) { return null; } - + return (
welcome, {props.name} @@ -5340,7 +5343,7 @@ super(props); this.state = {loggedIn: false, name: 'John'}; } - + render() { return (
@@ -5436,7 +5439,7 @@ import React, { Component } from 'react'; import './App.css'; import '@vaadin/vaadin-date-picker'; - + class App extends Component { render() { return ( @@ -5446,7 +5449,7 @@ ); } } - + export default App; ``` @@ -5477,9 +5480,9 @@ ```javascript import loadable from '@loadable/component' - + const OtherComponent = loadable(() => import('./OtherComponent')) - + function MyComponent() { return (
@@ -5499,7 +5502,7 @@ ```javascript const OtherComponent = React.lazy(() => import('./OtherComponent')); - + function MyComponent() { return (
@@ -5522,10 +5525,10 @@ ```javascript import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import React, { Suspense, lazy } from 'react'; - + const Home = lazy(() => import('./routes/Home')); const About = lazy(() => import('./routes/About')); - + const App = () => ( Loading...
}> @@ -5662,7 +5665,7 @@ } } ``` - + 可以通过把 value 的值提升到父状态中来解决这个问题: ```javascript @@ -5673,7 +5676,7 @@ value: {something: 'something'}, }; } - + render() { return ( @@ -5699,15 +5702,15 @@ console.log('old props:', prevProps); console.log('new props:', this.props); } - + render() { const {forwardedRef, ...rest} = this.props; - + // Assign the custom prop "forwardedRef" as a ref return ; } } - + return React.forwardRef((props, ref) => { return ; }); @@ -5721,7 +5724,7 @@ focus() { // ... } - + // ... } export default logProps(FancyButton); @@ -5731,7 +5734,7 @@ ```javascript import FancyButton from './FancyButton'; - + const ref = React.createRef(); ref.current.focus(); Hello {this.props.message}
; } } - + ReactDOM.render( , document.getElementById('root') @@ -5807,7 +5810,7 @@ return React.createElement('div', null, `Hello ${this.props.message}`); } } - + ReactDOM.render( React.createElement(Greeting, {message: 'World'}, null), document.getElementById('root') @@ -5870,7 +5873,7 @@
  • Duke
  • Villanova
  • - +