专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
OSC开源社区  ·  Bun ... ·  11 小时前  
程序猿  ·  41岁DeepMind天才科学家去世:长期受 ... ·  昨天  
程序员的那些事  ·  OpenAI ... ·  昨天  
OSC开源社区  ·  宇树王兴兴早年创业分享引围观 ·  3 天前  
程序猿  ·  “我真的受够了Ubuntu!” ·  3 天前  
51好读  ›  专栏  ›  SegmentFault思否

应对React面试前,必须要了解的25个话题(下)

SegmentFault思否  · 公众号  · 程序员  · 2019-06-03 19:55

正文


本文原载于SegmentFault专栏"终身学习者"

翻译自 Learn Enough React For The Interview

翻译:前端小智

整理编辑:SegmentFault


React是流行的javascript框架之一,在2019年及以后将会更加流行。React于2013年首次发布,多年来广受欢迎。它是一个声明性的、基于组件的、用于构建用户界面的高效javascript库。


以下是面试前必须了解的话题, 今天我们为大家分享其中的下半部分——

  • 什么是声明式编程

  • 声明式编程 vs 命令式编程

  • 什么是函数式编程

  • 什么是组件设计模式

  • React 是什么

  • React 和 Angular 有什么不同

  • 什么是虚拟DOM及其工作原理

  • 什么是JSX

  • 组件和不同类型

  • Props 和 State

  • 什么是 PropTypes

  • 如何更新状态和不更新状态

  • 组件生命周期方法

  • 超越继承的组合

  • 如何在React中应用样式

  • 什么是Redux及其工作原理

  • 什么是React路由器及其工作原理

  • 什么是错误边界

  • 什么是 Fragments

  • 什么是传送门(Portals)

  • 什么是 Context

  • 什么是 Hooks

  • 如何提高性能

  • 如何在重新加载页面时保留数据

  • 如何从React中调用API

  • 总结


相关阅读:

应对React面试前,必须要了解的25个话题(上)


超越继承的组合


在React中,我们总是使用组合而不是继承。我们已经在函数式编程部分讨论了什么是组合。这是一种结合简单的可重用函数来生成高阶组件的技术。下面是一个组合的例子,我们在 dashboard 组件中使用两个小组件 todoForm todoList

import React from 'react';import '../App.css';import { ToDoForm } from './todoform';import { ToDolist } from './todolist';
export class Dashboard extends React.Component {
render() { return ( <div className="dashboard"> <ToDoForm /> <ToDolist /> div> ); }}


如何在React中应用样式


将样式应用于React组件有三种方法。


外部样式表


在此方法中,你可以将外部样式表导入到组件使用类中。 但是你应该使用 className 而不是 class 来为React元素应用样式, 这里有一个例子。

import React from 'react';import './App.css';import { Header } from './header/header';import { Footer } from './footer/footer';import { Dashboard } from './dashboard/dashboard';import { UserDisplay } from './userdisplay';
function App() { return ( <div className="App"> <Header /> <Dashboard /> <UserDisplay /> <Footer /> div> );}
export default App;


内联样式


在这个方法中,我们可以直接将 props 传递给HTML元素,属性为 style 。这里有一个例子。这里需要注意的重要一点是,我们将javascript对象传递给style,这就是为什么我们使用 backgroundColor 而不是CSS方法 backbackground -color

import React from 'react';
export const Header = () => {
const heading = 'TODO App'
return( <div style={{backgroundColor:'orange'}}> <h1 >{heading}h1> div> )}


定义样式对象并使用它


因为我们将javascript对象传递给 style 属性,所以我们可以在组件中定义一个 style 对象并使用它。下面是一个示例,你也可以将此对象作为 props 传递到组件树中。

import React from 'react';
const footerStyle = { width: '100%', backgroundColor: 'green', padding: '50px', font: '30px', color: 'white', fontWeight: 'bold'}
export const Footer = () => { return( <div style={footerStyle}> All Rights Reserved 2019 div> )}



什么是Redux及其工作原理


Redux 是 React的一个状态管理库,它基于flux。 Redux简化了React中的单向数据流。 Redux将状态管理完全从React中抽象出来。


它是如何工作的


在React中,组件连接到 redux ,如果要访问 redux,需要派出一个包含 id 和负载(payload) 的 action 。action 中的 payload 是可选的,action 将其转发给 Reducer。

reducer 收到 action 时,通过 swithc...case 语法比较 action type 。 匹配时,更新对应的内容返回新的 state


Redux 状态更改时,连接到 Redux 的组件将接收新的状态作为 props 。当组件接收到这些 props 时,它将进入更新阶段并重新渲染 UI。

Redux 循环细节


让我们详细看看整个redux 循环细节。

Action : Action 只是一个简单的json对象, type 和有 payload 作为键。 type 是必须要有的, payload 是可选的。下面是一个 action 的例子。

// action
{ type:"SEND_EMAIL", payload: data};

Action Creators :这些是创建 Actions 的函数,因此我们在派发 action 时不必在组件中手动编写每个 action 。 以下是 action creator 的示例。

// action creator
export function sendEamil(data) { return { type:"SEND_EMAIL", payload: data};}

Reducers :Reducers 是纯函数,它将 action 和当前 state 作为参数,计算必要的逻辑并返回一个新r的 state 。 这些 Reducers 没有任何副作用。 它不会改变 state 而是总是返回 state

export default function emailReducer(state = [], action){   switch(action.type) {      case "SEND_EMAIL":  return Object.assign({}, state, {       email: action.payload      });      default: return state;  }}


组件如何与 redux 进行连接


mapStateToProps :此函数将 state 映射到 props 上,因此只要 state 发生变化,新 state 会重新映射到 props 。 这是订阅 store 的方式。


mapDispatchToProps :此函数用于将 action creators 绑定到你的 props 。以便我们可以在第 12 行中使用This . props.actions.sendemail() 来派发一个动作。


connect bindActionCreators 来自 redux。 前者用于连接 store ,如第22行,后者用于将 action creators 绑定到你的 props ,如第20行。

// import connectimport { connect } from 'react-redux'import { bindActionCreators } from 'redux'
// import action creatorsimport * as userActions from '../../../actions/userActions';
export class User extends React.Component { handleSubmit() { // dispatch an action this.props.actions.sendEmail(this.state.email); } }
// you are mapping you state propsconst mapStateToProps = (state, ownProps) => ({user: state.user})// you are binding your action creators to your propsconst mapDispatchToProps = (dispatch) => ({actions: bindActionCreators(userActions, dispatch)})
export default connect(mapStateToProps, mapDispatchToProps)(User);


什么是 React Router Dom 及其工作原理


react-router-dom 是应用程序中路由的库。 React库中没有路由功能,需要单独安装 react-router-dom

react-router-dom 提供两个路由器 BrowserRouter HashRoauter 。前者基于rul的pathname段,后者基于hash段。

前者:http://127.0.0.1:3000/article/num1
后者:http://127.0.0.1:3000/#/article/num1(不一定是这样,但#是少不了的)


react-router-dom 组件

  • BrowserRouter HashRouter 是路由器。

  • Route 用于路由匹配。

  • Link 组件用于在应用程序中创建链接。 它将在HTML中渲染为锚标记。

  • NavLink 是突出显示当前活动链接的特殊链接。

  • Switch 不是必需的,但在组合路由时很有用。

  • Redirect 用于强制路由重定向


下面是组件中的 Link NavLink Redirect 的例子

// normal link"/gotoA">Home
// link which highlights currentlu active route with the given class name"/gotoB" activeClassName="active"> React
// you can redirect to this url"/gotoC" />

以下是 react router 组件的示例。 如果你查看下面的示例,我们将匹配路径并使用 Switch Route 呈现相应的组件。

import React from 'react'// import react router DOM elementsimport { Switch, Route, Redirect } from 'react-router-dom'import ComponentA from '../common/compa'import ComponentB from '../common/compb'import ComponentC from '../common/compc'import ComponentD from '../common/compd'import ComponentE from '../common/compe'

const Layout = ({ match }) => { return(
)}
export default Layout



什么是错误边界


在 React 中,我们通常有一个组件树。如果任何一个组件发生错误,它将破坏整个组件树。没有办法捕捉这些错误,我们可以用错误边界优雅地处理这些错误。


错误边界有两个作用

  • 如果发生错误,显示回退UI

  • 记录错误


下面是 ErrorBoundary 类的一个例子。如果类实现了 getDerivedStateFromError componentDidCatch 这两个生命周期方法的任何一下,,那么这个类就会成为 ErrorBoundary 。前者返回 {hasError: true} 来呈现回退UI,后者用于记录错误。

import React from 'react'
export class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { // Update state so the next render will show the fallback UI. return { hasError: true }; } componentDidCatch(error, info) { // You can also log the error to an error reporting service console.log('Error::::', error); } render() { if (this.state.hasError) { // You can render any custom fallback UI return <h1>OOPS!. WE ARE LOOKING INTO IT.h1>; } return this.props.children; } }

以下是我们如何在其中一个组件中使用ErrorBoundary。使用ErrorBoundary类包裹 ToDoForm ToDoList 。 如果这些组件中发生任何错误,我们会记录错误并显示回退UI。

import React from 'react';import '../App.css';import { ToDoForm } from './todoform';import { ToDolist } from './todolist';import { ErrorBoundary } from '../errorboundary';
export class Dashboard extends React.Component {
render() { return ( <div className="dashboard"> <ErrorBoundary> <ToDoForm /> <ToDolist /> ErrorBoundary> div> ); }}


什么是 Fragments


在React中,我们需要有一个父元素,同时从组件返回React元素。有时在DOM中添加额外的节点会很烦人。使用 Fragments ,我们不需要在DOM中添加额外的节点。我们只需要用 React.Fragment 或才简写 <> 来包裹内容就行了。如下 所示:

 // Without Fragments   return (    <div>       <CompoentA />       <CompoentB />       <CompoentC />    div>)
// With Fragments return ( <React.Fragment> <CompoentA /> <CompoentB /> <CompoentC /> React.Fragment> )
// shorthand notation Fragments return ( <> <CompoentA /> <CompoentB /> <CompoentC /> > )



什么是传送门(Portals)

默认情况下,所有子组件都在UI上呈现,具体取决于组件层次结构。Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。

这里有一个例子。默认情况下,父组件在DOM层次结构中有子组件。

我们可以将 children 组件移出 parent 组件并将其附加 id someid 的 Dom 节点下。


首先,获取 id 为 someid,我们在constrcutorand中创建一个元素div,将child附加到componentDidMount中的someRoot。 最后,我们在ReactDOM.createPortal(this.props.childen),domnode的帮助下将子节点传递给该特定DOM节点。


首先,先获取 id 为 someid DOM元素,接着在构造函数中创建一个元素div,在 componentDidMount 方法中将 someRoot 放到 div 中 。 最后,通过
ReactDOM.createPortal(this.props.childen), domnode) children 传递到对应的节点下。

const someRoot = document.getElementById('someid');
class Modal extends React.Component { constructor(props) { super(props); this.el = document.createElement('div'); }
componentDidMount() { someRoot.appendChild(this.el); }
componentWillUnmount() { someRoot.removeChild(this.el); }
render() { return ReactDOM.createPortal( this.props.children, this.el, ); }}

什么是上下文


有时我们必须将 props 传递给组件树,即使所有中间组件都不需要这些 props 。上下文是一种传递 props 的方法,而不用在每一层传递组件树。


什么是 Hooks


Hooks 是React版本16.8中的新功能。 请记住,我们不能在函数组件中使用 state ,因为它们不是类组件。 Hooks 让我们在函数组件中可以使用 state 和其他功能。







请到「今天看啥」查看全文