作者:@Tyler
原文 有删改
- 在
React
当中Element
和Component
有何区别?
简单地说,一个 React element 描述了你想在屏幕上看到什么。换个说法就是,一个 React element 是一些 UI 的对象表示。
一个 React Component 是一个函数或一个类,它可以接受输入并返回一个 React element (通常是通过 JSX ,它被转化成一个 createElement 调用)。
- 什么时候在功能组件(
Functional Component
)上使用类组件(Class Component
)?
如果您的组件具有状态( state )或生命周期方法,请使用 Class 组件。否则,使用功能组件
- 什么是
React
的refs
,为什么它们很重要?
refs 就像是一个逃生舱口,允许你直接访问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 元素 input,以便在 handleSubmit 函数内部访问它。经常被误解的是,您需要使用类组件才能使用ref ,但 ref 也可以通过利用 JavaScript 中的闭包与 功能组件( functional components )一起使用
function CustomForm ({handleSubmit}) {
let inputElement
return (
<form onSubmit={() => handleSubmit(inputElement.value)}>
<input
type='text'
ref={(input) => inputElement = input} />
<button type='submit'>Submit</button>
</form>
)
}
- 通过渲染回调模式(
render callback pattern
)将函数而不是另外一个子组件作为父组件的child
// 父组件
<Twitter username='tylermcginnis33'>
{(user) => user === null
? <Loading />
: <Badge info={user} />}
</Twitter>
// 父组件结构
import React, { Component, PropTypes } from 'react'
// fetchUser接收用户名返回 promise
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)
}
}
这种模式的好处是我们已经将父组件与子组件分离了。父组件管理状态,父组件的调用者可以决定以何种方式将从父级接收的参数应用于他们的 UI
- 在哪个生命周期事件中你会发出 AJAX 请求,为什么?
AJAX 请求应该在 componentDidMount 生命周期事件中。
- 为什么要使用 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 可能是一个数组或一个对象。
- 可以选择性地传递给 setState 的第二个参数是什么,它的目的是什么?
一个回调函数,当setState
结束并re-rendered该组件时将被调用, setState
是异步的,这就是为什么它需要一个第二个回调函数。通常最好使用另一个生命周期方法,而不是依赖这个回调函数,但是很高兴知道它存在
this.setState(
{ username: 'tylermcginnis33' },
() => console.log('setState has finished and the component has re-rendered.')
)
- 传递一个函数给
setState
this.setState((prevState, props) => {
return {
streak: prevState.streak + props.count
}
})
你也可以传递一个函数给setState
,它接收到先前的状态和道具并返回一个新的状态,正如我们在上面所做的那样。它不仅没有什么问题,而且如果您根据以前的状态(state
)设置状态,推荐使用这种写法。