ホームページ > 記事 > ウェブフロントエンド > React2018 の面接の質問は何ですか?面接の質問に対応するための標準的な回答の分析
この記事では主にreactに関するよくある面接の質問を紹介します
呼び出されるとき setState
时,React会做的第一件事情是将传递给 setState
オブジェクトはコンポーネントの現在の状態にマージされます。これにより、調整と呼ばれるプロセスが開始されます。調整の最終目標は、この新しい状態に基づいて最も効率的な方法で UI を更新することです。
これを行うために、React は新しい React
要素ツリーを構築します (UI のオブジェクト表現と考えることができます)。
このツリーを取得したら、新しい状態に応じて UI がどのように変化するかを理解するために、React はこの新しいツリーを前の要素ツリー ( diff ) と比較します。
これを行うことで、React は発生した正確な変更を認識し、何が変更されたかを知ることで、絶対に必要な場合にのみ更新することで UI のフットプリントを最小限に抑えることができます。
簡単に言うと、React 要素 は画面に表示したいものを記述します。言い換えれば、React 要素 は、何らかの UI のオブジェクト表現です。
A React Component は、入力を受け取り、React 要素t を返す関数またはクラスです (通常は JSX 経由で、createElement 呼び出しに変換されます)。
詳細については、React をご覧ください。 要素と React コンポーネント
コンポーネントに状態メソッドまたはライフサイクル メソッドがある場合は、クラス コンポーネントを使用します。それ以外の場合は、機能コンポーネントを使用します
ref は脱出ハッチのようなもので、DOM 要素またはコンポーネント インスタンスに直接アクセスできるようにします。これらを使用するには、コンポーネントに ref 属性を追加します。その値は、基礎となる DOM 要素またはコンポーネントのマウントされたインスタンスを最初の引数として受け取るコールバック関数です。
class UnControlledForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' ref={(input) => this.input = input} /> <button type='submit'>Submit</button> </form> ) } }
上記の入力フィールドには ref 属性があり、その値は関数であることに注意してください。この関数は実際の DOM 要素を受け取り、handleSubmit 関数内でアクセスするためにインスタンスに配置します。 ref を使用するにはクラスコンポーネントを使用する必要があると誤解されることがよくありますが、 ref は JavaScript
の closure を利用することによっても使用できます。
機能部品と組み合わせて使用します。
function CustomForm ({handleSubmit}) { let inputElement return ( 7903c0d16121af01954846672cad07ea handleSubmit(inputElement.value)}> 90adf65a988b0fc262c10923fbcdf698 inputElement = input} /> eb45daf4af391dfc1a2ed2f3e690d49fSubmit65281c5ac262bf6d81768915a4a77ac0 f5a47148e367a6035fd7a2faa965022e ) }
キーは、どの項目がリストから変更、追加、または削除されたかを React が追跡するのに役立ちます。
return ( ff6d136ddc5fdfeffaf53ff6ee95f185 {this.state.todoItems.map(({task, uid}) => { return b80c825a615c52ebe2f730ce1cd3d995{task}bed06894275b65c1ab86501b08a632eb })} 929d1f5ca49e04fdcb27f9465b944689 ) }
各 keys は兄弟要素間で一意です。調整プロセスについては何度か説明しましたが、この調整プロセスの一部では、新しい要素ツリーと前の要素ツリーの間の差異が実行されます。 keys を使用すると、React が子要素で keys を使用して、ツリーを比較するときに要素が新しいか移動されたかをすぐに知ることができるため、リストの操作がより効率的になります。
そして keys はこのプロセスをより効率的にするだけでなく、 keys がないと、React は移動中のどのローカル状態がどのアイテムに対応するかを認識できません。したがって、マッピングするときは keys を無視しないでください。 (さらに詳しく知りたい場合は、PHP 中国語 Web サイトReact Reference Manual の列にアクセスして学習してください)
import React, { Component, PropTypes } from 'react'import fetchUser from 'twitter'// fetchUser接收用户名返回 promise// 当得到 用户的数据的时候 ,返回resolve 状态class Twitter extends Component { // 在这里写下你的代码}
如果你不熟悉渲染回调模式(render callback pattern),这将看起来有点奇怪。在这种模式中,一个组件接收一个函数作为它的 child。注意上面包含在 标签内的内容。 Twitter 组件的 child 是一个函数,而不是你曾经习以为常的一个组件。 这意味着在实现 Twitter 组件时,我们需要将 props.children 作为一个函数来处理。
以下是我的答案。
import React, { Component, PropTypes } from 'react'import fetchUser from 'twitter'class Twitter extends Component { state = { user: null, } static propTypes = { username: PropTypes.string.isRequired, } componentDidMount () { fetchUser(this.props.username) .then((user) => this.setState({user})) } render () { return this.props.children(this.state.user) } }
值得注意的是,正如我上面提到的,我通过调用它并传递给 user 来把 props.children 处理为为一个函数。
这种模式的好处是我们已经将我们的父组件与我们的子组件分离了。父组件管理状态,父组件的消费者可以决定以何种方式将从父级接收的参数应用于他们的 UI。
为了演示这一点,我们假设在另一个文件中,我们要渲染一个 Profile 而不是一个 Badge, ,因为我们使用渲染回调模式,所以我们可以轻松地交换 UI ,而不用改变我们对父(Twitter)组件的实现。
<Twitter username='tylermcginnis33'> {(user) => user === null ? <Loading /> : <Profile info={user} />}</Twitter>
React 的很大一部分是这样的想法,即组件负责控制和管理自己的状态。
当我们将 native HTML 表单元素( input, select, textarea 等)投入到组合中时会发生什么?我们是否应该使用 React 作为“单一的真理来源”,就像我们习惯使用React一样? 或者我们是否允许表单数据存在 DOM 中,就像我们习惯使用HTML表单元素一样? 这两个问题是受控(controlled) VS 不受控制(uncontrolled)组件的核心。
受控组件是React控制的组件,也是表单数据的唯一真理来源。
如下所示, username 不存在于 DOM 中,而是以我们的组件状态存在。每当我们想要更新 username 时,我们就像以前一样调用setState。
class ControlledForm extends Component { state = { username: '' } updateUsername = (e) => { this.setState({ username: e.target.value, }) } handleSubmit = () => {} render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' value={this.state.username} onChange={this.updateUsername} /> <button type='submit'>Submit</button> </form> ) } }
不受控制( uncontrolled component )的组件是您的表单数据由 DOM 处理,而不是您的 React 组件。
我们使用 refs 来完成这个。
class UnControlledForm extends Component { handleSubmit = () => { console.log("Input Value: ", this.input.value) } render () { return ( <form onSubmit={this.handleSubmit}> <input type='text' ref={(input) => this.input = input} /> <button type='submit'>Submit</button> </form> ) } }
虽然不受控制的组件通常更容易实现,因为您只需使用引用从DOM获取值,但是通常建议您通过不受控制的组件来支持受控组件。
主要原因是受控组件 支持即时字段验证 ,允许您有条件地禁用/启用按钮,强制输入格式,并且更多的是 『the React way』。
AJAX 请求应该在 componentDidMount
生命周期事件中。 有几个原因:
Fiber,是下一次实施React的和解算法,将有能力根据需要启动和停止渲染,以获得性能优势。其中一个取舍之一是 componentWillMount
,而在其他的生命周期事件中出发
AJAX 请求,将是具有 “非确定性的”。 这意味着 React 可以在需要时感觉到不同的时间开始调用 componentWillMount。这显然是AJAX请求的不好的方式。
-您不能保证在组件挂载之前,AJAX请求将无法 resolve。如果这样做,那意味着你会尝试在一个未挂载的组件上设置 StState,这不仅不会起作用,反而会对你大喊大叫。 在 componentDidMount
中执行
AJAX 将保证至少有一个要更新的组件。
上面我们讨论了 reconciliation ,什么是 React 在 setState 被调用时所做的。在生命周期方法 shouldComponentUpdate 中,允许我们选择退出某些组件(和他们的子组件)的 reconciliation 过程。
我们为什么要这样做?
如上所述,“和解( reconciliation )的最终目标是以最有效的方式,根据新的状态更新用户界面”。如果我们知道我们的用户界面(UI)的某一部分不会改变,那么没有理由让 React 很麻烦地试图去弄清楚它是否应该渲染。通过从 shouldComponentUpdate 返回 false,React 将假定当前组件及其所有子组件将保持与当前组件相同。
通常,您将使用Webpack的 DefinePlugin 方法将 NODE_ENV 设置为 production。这将剥离像 propType 验证和额外的警告。除此之外,还有一个好主意,可以减少你的代码,因为React使用 Uglify 的 dead-code 来消除开发代码和注释,这将大大减少你的包的大小。
为什么要使用 React.Children.map(props.children,()=>) 而不是 props.children.map(()=>)
因为不能保证props.children将是一个数组。
以此代码为例,
<Parent> <h1>Welcome.</h1></Parent>
在父组件内部,如果我们尝试使用 props.children.map 映射孩子,则会抛出错误,因为 props.children 是一个对象,而不是一个数组。
如果有多个子元素,React 只会使props.children成为一个数组。就像下面这样:
<Parent> <h1>Welcome.</h1> <h2>props.children will now be an array</h2></Parent>
这就是为什么你喜欢 React.Children.map
,因为它的实现考虑到 props.children
可能是一个数组或一个对象。
为了解决跨浏览器兼容性问题,您的 React 中的事件处理程序将传递 SyntheticEvent
的实例,它是 React 的浏览器本机事件的跨浏览器包装器。
这些 SyntheticEvent
与您习惯的原生事件具有相同的接口,除了它们在所有浏览器中都兼容。有趣的是,React 实际上并没有将事件附加到子节点本身。React
将使用单个事件监听器监听顶层的所有事件。这对于性能是有好处的,这也意味着在更新DOM时,React 不需要担心跟踪事件监听器。
createElement 是 JSX 被转载到的,是 React 用来创建 React Elements 的内容(一些 UI 的对象表示)cloneElement用于克隆元素并传递新的 props。他们钉住了这两个��的命名。
一个回调函数,当setState结束并 re-rendered
该组件时将被调用。一些没有说出来的东西是 setState 是 异步 的,这就是为什么它需要一个第二个回调函数。通常最好使用另一个生命周期方法,而不是依赖这个回调函数,但是很高兴知道它存在。
this.setState( { username: 'tylermcginnis33' }, () => console.log('setState has finished and the component has re-rendered.') )
this.setState((prevState, props) => { return { streak: prevState.streak + props.count } })
没毛病。但是这种写法很少被使用,并不是众所周知的,就是你也可以传递一个函数给setState,它接收到先前的状态和道具并返回一个新的状态,正如我们在上面所做的那样。它不仅没有什么问题,而且如果您根据以前的状态(state)设置状态,推荐使用这种写法。
この記事はここで終わります (さらに詳しく知りたい場合は、PHP 中国語 Web サイトReact ユーザー マニュアル の列にアクセスして学習してください)。ご質問がある場合は、以下にメッセージを残してください。
以上がReact2018 の面接の質問は何ですか?面接の質問に対応するための標準的な回答の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。