网站建设的界面f分,网站建设怎么解析域名,vi设计英文,wordpress系统版更新:收藏前点个赞亲#xff0c;为啥我每次写的东西收藏都是赞的n倍#xff01;#xff01;花了一个月时间总结的React面试题 希望能帮助到你全文近万字建议保存仔细过一遍目录面试中常提的重要概念React生命周期ReduxRouter重要的方法面试中常提的重要概念1 什么是模块化是…更新:收藏前点个赞亲为啥我每次写的东西收藏都是赞的n倍花了一个月时间总结的React面试题 希望能帮助到你全文近万字建议保存仔细过一遍目录面试中常提的重要概念React生命周期ReduxRouter重要的方法面试中常提的重要概念1 什么是模块化 是从代码的角度进行分析的。把一些可复用的代码抽成一个单独的模块便于项目维护和开发2 什么是组件化 是从ui的角度进行分析的 把一些可复用的ui元素抽成一个单独的组件便于项目的维护和开发3 组件化的好处随着项目的规模增大 手里的组件越来越多 很方便就能把现有的组件拼接成一个完整的页面4 DOM和虚拟DOMDOM的本质 浏览器中用js对象表示页面上的元素 并提供操作DOM的API虚拟DOM的本质这是框架中的概念 是程序员用js对象来模拟页面上的DOM和DOM的嵌套 为的是实现DOM的高效更新虚拟DOM是如何工作的虚拟DOM只不过是真实的DOM的javascript对象表示。与更新真实的DOM相比更新javascript对象更容易更快捷。React将整个DOM副本保存为虚拟DOM。每次更新时它都会维护两个虚拟DOM比较之前的状态和当前的状态并确定哪些对象已被更改。并将这些变化更新到实际的DOM上5 React如何提高性能5.1 适当地使用shouldComponentUpdate生命周期方法。 它避免了子组件的不必要的渲染。 如果树中有100个组件则不重新渲染整个组件树来提高应用程序性能。5.2 使用create-react-app来构建项目这会创建整个项目结构并进行大量优化。5.3 不可变性是提高性能的关键。不要对数据进行修改而是始终在现有集合的基础上创建新的集合以保持尽可能少的复制从而提高性能。5.4 在显示列表或表格时始终使用 Keys这会让 React 的更新速度更快5.5 多使用无状态组件(Function)5.6 代码分离是将代码插入到单独的文件中只加载模块或部分所需的文件的技术。6 React如何在重新加载页面时保留数据单页面应用程序首先在DOM中加载index.html然后在用户浏览页面时加载内容或者从同一index.html中后端API中获取任何数据。如果我们通过点击浏览器中的重新加载按钮 重新加载页面index.html整个React应用程序将重新加载我们将丢失应用程序的状态。如何保留应用状态每当重新加载应用程序时我们使用浏览器localstorage来保存应用程序的状态。我们将整个存储数据保存在localstorage中每当有页面刷新或重新加载时我们从localstorage加载状态。7 如何在React中应用样式1 外部样式表通过import导入外部样式表然后应用className 注意不是class2 内敛样式给style内接收的是一个对象形式的css注意css中的-自动去掉 并且下一个单词首字母大写style{{backgroundColor:red}}3 定义样式对象并应用const footerStyle {width: 100%,backgroundColor: red,padding: 20px,font: 20px,color: white,fontWeight: bold}
div style{footerStyle}/div
8 state8.1 一句话解释state和props的区别state是组件内部维护的一组用于反映组件ui变化的状态集合 是可变的props一般存在于子组件 通过父组件的state变化传递给子组件作业propss来更新视图8.2 state使用细节 1 state必须是一个对象2 this.setState方法一般情况是异步的 注意一般情况下特殊 在一些异步函数中 (定时器ajax,Promise)中setState是同步的8.3 什么时候可以定义一个state或者说是一个变量可否可以作为一个statestate不能定义过多因为如果使用了state就会给这个变量增加一些响应式挂载1 如果这个变量是通过props从父组件获取 他就不是一个状态2 如果这个变量可以通过其他状态state或是属性props 通过数据处理得到 那么他不是一个状态3 如果变量在render中没有使用到 那么他就不是一个状态4 如果变量在整个生命周期中都保持不变 那么他不是一个状态9 什么是jsxJSX 是JavaScript XML 的简写。是 javascript的语法扩展它利用 JavaScript 的表现力和类似 HTML 的模板语法来生成React元素并将这些元素在DOM中呈现下面是JSX的一个例子render(){return( divh1{{name}}/h1/div);
}浏览器无法识别jsx 需要babeljsx转化器将jsx转化为js对象10 什么是propsProps 是 React 中属性的简写。它们是只读组件必须保持纯即不可变。它们总是在整个应用中从父组件传递到子组件。子组件永远不能将 prop 送回父组件。这有助于维护单向数据流通常用于呈现动态生成的数据。11 什么是ReactReact是一个简单的javascript UI库用于构建高效、快速的用户页面。它是一个轻量级库因此很受欢迎。它遵循组件设计模式、声明式编程范式和函数式编程概念以使前端应用程序更高效。它使用虚拟dom来优秀地操作dom。它遵循从高阶组件到低阶组件的单项数据流12 React 中 keys 的作用是什么在开发过程中我们需要保证某个元素的 key 在其同级元素中具有唯一性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建的还是被移动而来的元素从而减少不必要的元素重渲染。此外React 还需要借助 Key 值来判断元素与本地状态的关联关系因此我们绝不可忽视转换函数中 Key 的重要性。13纯函数纯函数是始终接受一个或多个参数并计算参数然后返回数据或是函数的函数。14高阶函数高阶函数就是将 函数作为参数 或 返回函数 的函数 或者都有这些高阶函数可以操纵其他函数15什么是函数式编程 函数式编程是声明式编程的一部分声明式编程注重过程命令式编程注重结果函数式编程的几个部分1 不可变性 2纯函数 3数据转换 4高阶函数 5递归 6组合在react中我们将功能划分为小型可重用的纯函数我们必须将这些可重用的函数放在一起最终使其成为产品。将所有较小的函数组合成更大的函数最终得到一个应用程序这称为组合。16 diff算法三次对比 1 tree diff 新旧dom树逐层对比2 component diff 每一层进行组件级别的对比 只是对比组件类别3 element diff 组件相同时 进行元素级别的对比17 组件组件的类别分为 17.1 函数/无状态组件/展示组件函数或是无状态组件是一个纯函数他可接收参数并返回react元素并且没有任何副作用。但这些组件没有生命周期函数所以也叫展示组件export const Header () {return(div style{{backgroundColor:red}}h1Hello World/h1/div)
}17.2 类/有状态组件这就是我们在编写react中最经常创建的组件类同 通过class xx extends React.Component这类组件可以通过setState()来改变组件的状态并且可以使用生命周期函数17.3 容器组件容器组件用来包含展示其它组件或其它容器组件但里面从来都没有html。17.4 高阶组件其实和高阶函数的意思差不多。意思是将组件作为参数并生成另一个组件的组件。17.5 受控和非受控组件例如input option radio 他们的状态是不受react控制的 而是控件本身具有的 我们把这样的组件称为非受控组件非受控-受控组件的转化首先把状态绑定到非受控组件的value、checked上然后监听该组件的onChange事件 用e.target 获取input上面的数据 然后通过setState设置数据给state内的数据18 更新组件的正确方式和错误方式//错误方式
this.state.name 马东什么
//正确方式
this.setState({name:马东什么})//错误方式
this.setState({title: this.state.name this.props.type
})
//正确方式
this.setState((state, props) {title: state.name props.type
});19超越继承的组合compose在react中我们总是使用组合而不是继承组件中的组合 直接上例子import { UserForm } from ./userForm;
import { CompanyForm } from ./companyForm;export class FormList extends React.Component {render() {render() {return (div classNamedashboard UserForm /CompanyForm //div);}
}20 什么是 Fragmentsreact中我们需要有一个父元素去包裹其他react元素return (divdiv一步 01/div,div一步 02/div,div一步 03/div/div
)解决这个问题第一种方法是数组的方式 return [div一步 01/div,div一步 02/div,div一步 03/div];第二种方式就是 Fragmentsreturn (React.Fragmentdiv一步 01/div,div一步 02/div,div一步 03/div/React.Fragment
)并且它可以简写return (div一步 01/div,div一步 02/div,div一步 03/div/
)21类型检查随着时间推移应用程序变得越来越大,因此类型检查非常重要。ProTypes为组件提供类型检查import PropTypes from prop-types;具体实现通过上下文的示例22 什么是上下文在react中我们会遇见这么一个情况如果爷爷想传东西给孙子那么需要这么做爷爷-孙子-儿子如果层级特别深 那么如果通过props层层传递是明显不合理的。这时我们就需要用到context上下文 通过设置上下文 任意一个后代元素都可以直接取到上下文的内容 不需要层层传递//首先在父组件定义上下文 并且需要先标明上下文的类型通过 21的内容
//定义类型
static childContextTypes{color:PropTypes.string
}
//定义上下文属性
getChildContext(){//这里返回什么 上下文的内容就是什么return {color:this.state.color}//先定义出这个属性constructor(props){super(props);this.state{color:red}
}
然后是后代元素 可以使子元素也可以是孙子元素 等等等
//后代必须验证 不验证就没有 上下文
static contextTypes{color:PropTypes.string
}然后就可以直接通过this.context.color来取出上下文的这个属性return (divh1 style{{color:this.context.color}}孙子/h1/div
)React生命周期初始化阶段default 是默认 预设的意思 init是初始化 这两个单词含义不同getDefaultProps() 设计初始的props getInitialState() 可以定义this.state 并且此时可以访问this.props其实都可以在里construstor设置 这两个钩子函数很少用componentWillMount 此时可以修改status 但是千万不要在这里拿数据 render()componentDidMount 很重要的钩子函数 此时已经讲组件渲染出来了 推荐在这里拿数据并更新这里可以具体查下为什么在这个阶段去请求数据其实上面这个阶段可以分为 inti阶段和Mounting阶段更新阶段componentWillReceiveProps(nextProps) 接收新的props时用!!shouldComponentUpdata(nextProps,nextState)react性能优化非常重要的额一环。组件接收新的state或props时 调用 我们可以设置在此时对比前后两个props和state是否相同如果相同 则返回false阻止更新 因为相同的属性状态一定会产生相同的dom树这样就不用创造新的dom树和旧的dom树进行diff算法对比。节省大量的性能优化 尤其是在dom结构复杂的时候案例再用redux进行状态管理时 很重要的一个优化就是判断状态是否改变当点击商品分类时 点击不同的分配组件的数据都会更新 但是如果点击的是和现在展示的相同的分类 这时让组件再更新一遍就很浪费性能就可以使用这个钩子函数 判断 状态是否改变 只有改变时 才会出发更新componentWillUpdata(nextProps,nextState)此时可以修改staterender()componentDidupdata()更新完成 此时可以获取DOM节点卸载 componentWillUnmount()组件要卸载时调用一些监听和定时器需要在此时清除ReduxRedux是React的一个状态管理仓库为了解决React组件通信和组件间状态共享为何要使用ReduxReact 是单向数据流也就是 props 只能从父组件一层一层向子组件传递而当数据流动复杂时 也就时子组件的状态改变会影响父组件的改变 而父组件改变又会引起其他子组件改变这时由于 props 的单向传递就需要父组件将需要改变的状态 和能够改变这个状态的函数 用props 一层一层传递下去 然后子组件一改变 一直逐层调用回调函数 完成各个组件的更新在这种情况下 就需要使用reduxredux 只能使用dispatch来完成组件的更新当子组件状态改变时 dispatch监控 然后传到reducer reducer判断是哪钟状态改变 然后直接去改变store(状态库)里的数据 然后store直接将数据分发到需要改变的组件中省去了反复回调的麻烦图片解释图片出处justjavac4 张动图解释为什么什么时候使用 Redux项目第一天项目第五天项目第20天使用redux介绍redux 官方的解释是 redux 是javascript的状态容器我的理解是 redux是为了解决react组件间的通信和组件间的状态共享而提出的一种解决方案 它包括 storeactionreducer 1 store 用来存储react状态机 state的对象 跟组件connect后 store 的改变就会驱动 组件的更新2 action 用于接收state的改变命令 是改变state的唯一途径和入口3 reducer 是action的处理器 1监控是action的哪种type变化 用于修改store中的state值 返回一个新的state组件间的通信1 由于connect后 各个connect组件共享store 所以各个组件可以通过store来进行数据通信规则 view由dispatch引起改变 然后 去触发reducer改变 store 然后引起组件的更新2通过对象驱动组件进入生命周期对于一个react组件来说 只能对自己的state改变驱动自己的生命周期或是通过外部传入props进行驱动而通过redux可以通过store来改变state 来驱动组件更新3方便进行数据管理和切片redux通过对store的管理和控制可以很方便的实现页面状态的管理和切片redux 三大原则1单一数据源2状态是只读的3状态得修改均有纯函数完成Router种类1.react-router是浏览器和原生应用的通用部分。2.react-router-dom是用于浏览器的。3.react-router-native是用于原生应用的。这里只说react-router-domreact-router-dom是应用程序中路由的库。React库中没有路由功能需要单独安装react-router-dom1.它提供两个路由器 BrowserRouter和HashRouterBrowserRouter这是对Router接口的实现。使得页面和浏览器的history保持一致。等于window.location。HashRouter和上面的一样只是使用的是url的hash部分等于window.location.hash前者http://127.0.0.1:3000/user/type后者http://127.0.0.1:3000/#/user/type不一定是这样但#是少不了的如果你使用的是一个非静态的站点、要处理各种不同的url那么你就需要使用BrowserRouter。相反的如果你的server只处理静态的url那么就使用HashRouter。2.react-router-dom组件BrowserRouter和HashRouter是路由器Route用于路由匹配Link组件用于在应用程序中创建链接。它讲在HTML中渲染为锚标记NavLink是突出显示当前活动链接的特殊链接。Switch 不是必需的但在组合路由时很有用。Redirect 用于强制路由重定向//示例
// normal link
Link to/gotoAHome/Link// link which highlights currentlu active route with the given class name
NavLink to/gotoB activeClassNameactiveReact
/NavLink// you can redirect to this url
Redirect to/gotoC ///示例
import React from react
// import react router DOM elements
import { 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/compeconst Layout ({ match }) {return(div classNameSwitchRoute exact path{${match.path}/gotoA} component{ComponentA} /Route path{${match.path}/gotoB} component{ComponentB} /Route path{${match.path}/gotoC} component{ComponentC} /Route path{${match.path}/gotoD} component{ComponentD} /Route path{${match.path}/gotoE} component{ComponentE} //Switch/div)}export default LayoutLink、RedirectLink to{{pathname: /me,search: ?sortasc,hash: #hash,state: { fromHome: true }
}} /Redirect to {{pathname: /register,search: ?utmsomething,state: { referrer: someplage.com }
}}重要的方法1 combineReducers from redux随着应用变得复杂需要对reducer函数进行拆分,拆分后每一块独立负责管理state的一部分combineReducers 辅助函数的作用是把一个由多个不同reducer函数作为value的object合并成一个最终的reducer函数然后就可以对这个reducer函数调用createStore2 applyMiddleware from redux添加中间件中间件redux提供了通过利用中间件来扩展自身功能以满足用户需求因为在整个数据操作过程中 reducer是纯函数 不能做额外的处理 在view视图层显然也不行所以只能在dispatch过程中做额外的处理 比如保存日志等等操作而这些额外的处理就叫做中间件 middlew而applyMiddleware(...middlewares) 可以在其中传入多个中间件 在action过程中添加更多处理过程并且每个中间件都有自己的熔断处理当他认为这个action不需要后面的中间件进行处理时后面的中间件也就不能对这个action进行处理而为什么不同的中间件可以组合使用 因为redux要求所有的中间件必须提供统一的接口3 redux-thunk中间件 thunkMiddleware等同于react-thunk 都是为了实现action的异步将同步的action转化成异步的action 适合用于api请求场景4 applyMiddleware(thunkMiddleware)(createStore)(reducers) 这种写法什么意思正常写法const store createStore(reducer,applyMiddleware(thunk));applyMiddleware函数参数是中间件会返回一个函数那个函数会接受一个store然后在返回一个函数而这个函数还会返回一个函数参数是reducer5 withRouter from react-router-dom将组件和withRouter组件绑定 可以获取到history对象withRouter 会在render时把更新后的match,location,history传递给包裹组件6 bindActionCreators from redux他将单个或多个ActionCreator转化为dispatch(action)的函数集合形式。开发者不用再手动dispatch(actionCreator(type))而是可以直接调用方法。好处1 将dispath触发规则单独抽离出去 便于维护2 多个组件可重复调用