React Native是一个用于在iOS、Android和UWP上渲染移动应用程序的库. 使用React Native, 在大多数情况下,编写一次代码并将其部署到所有可用的目标平台是可能的——这可能是您希望聘请专门的React Native专家的原因.
React Native与React共享许多概念和库, 所以对于任何React Native工作来说,开发者至少要熟悉web上的React及其常用模式,这一点很重要. 我们还建议React Native程序员精通JavaScript,尤其是ES6语法.
我们的许多问题 React招聘指南 在为React Native招聘应用开发者时也同样适用, 所以在面试的时候最好把这两个指南都记在心里. Of course, the JavaScript招聘指南 也适用于:正如指南中提到的, 对JavaScript框架有一些了解和成为JavaScript专家之间有很大的区别, 在从事React和React Native工作时,成为JavaScript专家是至关重要的.
回答地道的面试问题
让我们深入了解一些React Native面试问题来帮助你评估你的候选人.
什么是React Native组件?
组件是React Native应用程序的构建块. React Native提供了一组组件,这些组件映射到React Native专家可以使用的每个平台上相应的本地组件.
有些组件可以在所有平台上使用(例如 View
, Button
, and FlatList
),而其他则是特定于平台的, 因为它们映射到只存在于iOS或Android上的本地组件, iOS没有硬件返回按钮, so a BackHandler
组件在iOS应用中是没有意义的.
控件创建自己的组件 React.Component
类,并实现 Render
method:
导出默认类App扩展React.Component {
render() {
return (
//组件的可视树
);
}
}
React Native提供了 VirtualizedList
提供开箱即用的虚拟化的组件. While VirtualizedList
可以直接使用,越高级越好 FlatList
(在可滚动列表中显示项目)和 SectionList
(same as FlatList
但是使用分组和自定义部分)实现适合大多数用例.
在使用时,需要记住一些重要的事情 VirtualizedList
, however.
不能保证在滚动列表时保持列表中项的内部状态:基于元素的数量和滚动的级别, 列表可能会在视窗之外处理一些元素. 这些元素将基于从头开始重新创建 props
当返回viewport时. 因此,开发人员需要确保项目可以基于 props
alone.
项目应注明 Key
属性,该属性唯一标识它们. 另外,也可以提供自定义 KeyExtractor
在该列表的定义中:
这是一个很好的做法,以确保列表项不会重新渲染,如果传递相同的道具,他们已经有. 这可以通过实现来实现 shouldComponentUpdate
的组件中,或者从 React.PureComponent
类的实现 shouldComponentUpdate
that does shallow prop
and state
comparison.
如何在React Native中为组件设计样式?
样式是由纯JavaScript对象指定的,所有React Native组件都接受 Style
属性,该属性可以用指定样式的对象设置.
注意,虽然语法类似于CSS, it’s not CSS, React Native应用的组件样式也不遵循相同的约定. 值得注意的是,所有属性都遵循驼峰大小写约定,而不是破折号大小写(background-color
becomes backgroundColor
)和布局只能使用flexx算法指定.
因为样式定义是在代码中完成的, 它很容易参数化样式,并做一些通常CSS预处理器/扩展(少, Sass)用于:
import {StyleSheet} from 'react-native';
导入{primaryColor, secondaryColor}./style/consts'; // values defined in another .js file
let width = 50;
///...
const style = StyleSheet.create({
“颜色”:primaryColor,
“写成backgroundColor”:secondaryColor,
'width': width
});
如何调试React Native应用程序?
在模拟器中运行React Native应用程序时, 可以通过“摇动”设备(在模拟器中选择“摇动”手势)或按Command-D (iOS)或Control/Command-M (Android)来访问开发人员菜单。. 开发人员菜单将显示“启用JS调试”菜单项,以及其他内容. 单击它后,可以浏览到 http://localhost:8081/debugger-ui 使用Chrome/Chromium,显示调试器.
通过运行可以看到日志跟踪 react-native log-android
for Android, and react-native log-ios
对于iOS,当模拟器启动时.
If using Redux, Reactotron 看到所有API调用和动作调度特别有用吗.
我们现有的代码库在Xamarin中,你将帮助将其移植到React Native. 需要关注哪些问题?
不像我们其他的React Native面试问题,这可能并不适用于每个项目. 但如果确实如此,这当然是一个值得考虑的重要问题.
React Native and Xamarin.Forms 采用相同的方法制作跨平台应用程序:都采用UI定义(虚拟DOM或XAML)并将其转换为本机代码.
两者之间有两个主要区别:
- 选择的语言:xamarin几乎总是使用c#——尽管也可能使用其他语言 .. NET框架和用于React Native的JavaScript.
- 它们可用的开发平台:React Native可用于Linux, MacOS, and Windows, 而Xamarin仅在Windows和MacOS上正式可用.
而React Native和Xamarin.表单在概念上做同样的事情,它们使用的抽象并不直接兼容. For example, React Native上可用的组件不一定在Xamarin上可用, and vice versa. 同样,相同的抽象通常在两个框架中以不同的方式实现 FlatList
and SectionList
在React Native上,这映射到他们在iOS和Android上的相应概念,以及 ListView
on Xamarin.表单,它将两者合并为一个UI组件.
如果React Native开发者要处理Xamarin的移植.Forms, 对他们来说,至少有一些c#的经验是非常有益的, 最好有使用沙玛林的经验.
React和React Native之间的关系是什么?
React是一个JavaScript库,允许开发人员以声明式的方式定义用户界面. 在国家处理方面,它提供了一些基础设施(props
对于单向数据流,从外部注入; state
对于双向数据流(内部管理状态)和通用组件生命周期方法钩子.
React在内存中保留了UI的内部表示(虚拟DOM)。. 它使用这种表示来计算组件在道具/状态变化时的视觉外观变化, 以便能够在数据更改时部分更新UI——从而避免完全重绘的需要.
React Native位于React和之上, React会在哪里将虚拟DOM渲染为HTML文档, React Native将虚拟DOM映射到原生iOS/原生Android组件. So, 而React通常与JSX一起使用,以生成HTML输出, React Native有自己的一组标记,用来表示本地组件的抽象. 这些本地组件最终会显示在设备上.
所以,如果一个React组件看起来像这样:
类ReactJSComponent扩展React.Component {
render() {
return(
);
}
}
那么一个等效的React Native组件可能是这样的:
类reactativecomponent扩展React.组件{//注意,这是我们要扩展的同一个类
render() {
return(
Hello world!
);
}
}
通常用于处理状态的库(Redux), MobX)和大多数不依赖于UI的插件在React和React Native中的使用方式完全相同, 大多数适用于React的模式/最佳实践也适用于React Native.
强调原生开发和使用React native的移动开发之间的主要区别和权衡.
React Native在以下方面有明显的优势 移动应用开发:
- React Native允许跨平台开发:只编写一次应用程序逻辑, 使用相同的语言(JavaScript),并且可以部署到可用的目标平台(iOS, Android, and UWP). 为特定平台编写原生应用程序需要在将应用程序移植到不同平台时进行几乎完全的重写.
- React Native应用程序是用JavaScript编写的,有一些限制(见下文). 这可以是加号,也可以是减号,取决于具体情况, but generally, 寻找具有JavaScript经验的开发人员并不像寻找其他语言开发人员那样困难.
- 热重新加载是一个很棒的React Native特性, 允许开发人员更改应用程序代码并直接在模拟器中查看这些更改, 不需要重新编译/重新部署.
React Native是一个不错的选择, 特别是考虑到不断增加的用户基础和对它的不断改进. 但也有一些缺点需要考虑:
- 虽然在过去的两年里,业绩一直在稳步提高, React Native仍然比视觉效果相当的原生应用慢得多, 特别是当应用程序大量使用动画或具有复杂的UI时.
- 有些原生功能不能直接从React native中使用, 并且可能有必要为每个目标平台编写模块, 使用目标平台的语言.
- JavaScript是一种主流语言,因此被广泛了解和使用, 但它也有一些严重的缺点. 编写和维护一个扩展到一定规模的JavaScript应用程序可能是一项挑战.
React Native采用虚拟DOM,由React根据接口定义i生成.e. 方法得到的结果 render
方法在应用程序的组件上. 然后使用它为每个目标平台生成本机代码.
That means that, 在很大程度上, 开发人员不必担心平台特定的细节,可以依靠React Native根据情况输出正确的本地代码. 例如,如果开发人员添加 Text
组件,它将被转换为 UITextField
在iOS上,变成 TextView
on Android. 布局定义也是如此:React Native使用flexbox, 在部署应用程序时,这将被转换为特定于目标平台的适当布局定义.
有时,React Native提供的抽象只在某些目标平台上可用(前面提到的例子就是一个例子) BackHandler
). 在这种情况下,开发人员应该正确地利用抽象. 可能需要对当前平台进行检查:
从'react-native'中导入{Platform};
if (Platform.OS == 'ios') {
// ios特有的代码
}
在某些情况下,React Native并没有为本地组件或功能提供抽象层. 在这种情况下,开发人员将不得不用目标平台的语言编写本地模块. 这是通过扩展 ReactContextBaseJavaModule
Android应用程序,并通过实现 RCTBridgeModule
in iOS.
有了这些模块, 可以使用模块本身显式提供的端点从React Native与它们交互. 我们简单地用 @ReactMethod
导出类和方法 RCT_EXPORT_MODULE
and RCT_EXPORT_METHOD
on iOS:
公共类MyModule扩展ReactContextBaseJavaModule
@ReactMethod
公共无效myMethod() {
// implementation
}
}
@ implementation MyModule里
RCT_EXPORT_MODULE ();
RCT_EXPORT_METHOD (myMethod)
{
// implementation
}
从“react-native”中导入{native模块};
//这样调用它:
NativeModules.MyModule.myMethod();
在React Native中处理状态有哪些不同的选择?
事实上,React(以及React Native)不强制任何类型的全局状态管理. 开发人员可以使用的唯一模式是将状态注入到组件中 props
,而内部组件状态则通过 state
property.
当涉及到全局状态管理时,有几个选项可用, 更广泛使用的是Redux. 如果开发人员熟悉React上的Redux, 在React Native上使用它是没有变化的. 行为是完全相同的,因为是常见的使用模式.
管理全局状态的另一个可用选项是MobX, 哪个使用可观察对象和绑定处理状态, the way Knockout.js and WPF do. 而Redux遵循函数式编程范式,并且适合这种编程风格, 因此,对于那些具有面向对象背景的人来说,mobx更容易上手.
两个选项都是有效的, 在选择其中一个之前,考虑团队的组成是很重要的. Redux通常是具有函数式编程背景的人的首选, 但要跟上速度是很有挑战性的. MobX提供了更平坦的学习曲线, 但是,当应用程序增长到一定规模时,可能会出现问题.
What is a Thunk?
一般来说,Thunk是由另一个函数返回的函数. 它用于将计算结果推迟到实际需要结果的时候:
函数doMyThing() {
返回函数(){
返回"my result";
}
}
这个概念对React(和React Native)开发人员来说很重要,因为它们被用于Redux最流行的中间件之一:Redux -thunk. 它允许React操作,通常只是普通的JavaScript对象,像这样:
{
类型:“MY_ACTION_TYPE”,
value: "myvalue"
}
来直接调度其他动作,像这样:
函数myActionCreator() {
返回函数(调度,状态){
调度(anotherActionCreator ());
}
}
Redux还有其他的中间件没有直接暴露这个概念——最著名的是React saga——但是非常重要的是,你的React Native开发人员候选人熟悉上面的函数式编程概念.
什么是中间件? 它在Redux中是如何使用的?
Redux中间件是开发人员提供给Redux的功能(从外部模块导入), (或直接开发),在到达减少器之前拦截所有已分派的动作, 可能对这些操作执行一些操作, 然后将它们转发给减速机.
因此,中间件提供了一个钩子,可用于在动作到达reducer之前对其运行自定义操作. 这一点很重要,因为许多库和扩展(例如.g.(前面提到的redux-thunk)将自己注册为中间件. 一个中间件返回一个Thunk,因为它是一个返回函数的函数.
一个中间件实现示例如下:
//什么都不做的中间件
const myMiddleware = store => next => action => {
返回下一个(行动);
}
Here, store
应用程序的存储是否可以从中间件函数内部获得. That means that store.dispatch
是否可以从中间件内部获得, 这样就可以为每个接收到的操作分派多个操作——小心无限循环! Then next
是一个函数,返回一个函数(这将调度动作),并期望一个动作作为参数.
上述中间件可以通过以下方式注册:
const store = createStore()
myCombinedReducers,
applyMiddleware (myMiddleware otherMiddleware)
)
衡量你的React原生应用开发候选人
这些问题的答案应该能让你了解一个移动应用开发候选人在多大程度上适应React Native.
这份招聘指南, of course, 不是为了报道一次详尽的采访吗, 但作为聘请全职或兼职专家的指导方针——React Native开发和应用开发都有更多的内容. For example, 一个对JavaScript和React都非常有经验的专业开发人员应该能够很快地掌握React Native及其概念.
At the same time, 有一点React原生开发经验但没有JavaScript或原生开发经验的人可能知道上面问题的答案, 但作为一个React Native应用开发者却不是很有效. 你的里程可能会有所不同,就像生活中的其他事情一样. Good luck!