-
React的本质?
从Model 到 View 的映射。假设状态永远不变,那么实际上函数组件就相当于是一个模版引擎,只执行一次。
但是React本身正是为了动态的状态变化而设计的,而可能引起状态变化的原因基本只有两个:
-
用户操作产生的事件,比如点击了某个按钮
-
副作用产生的事件,比如发起某个请求正确返回了
例子:一个用于显示博客文章的组件,接收一个文章的id作为参数,然后根据这个id从服务器端获取文章内容并显示,并检测id的变化,重新发送请求。
如果在 class 组件,需要这样实现(用到2个生命周期方法):
class BlogView extends React.Component {// ...componentDidMount() {// 组件第一次加载时去获取Blog数据fetchBlog(this.props.id)}componentDidUpdate(prevProps) {// 当Blog的id变化时去获取博客文章if (prevProps.id !== this.props.id) {fetchBlog(this.props.id)}}
}
而在函数组件中,只需要useEffect即可:
function BlogView( {id} ) {useEffect(() => {// 当id变化时,重写获取博客文章fetchBlog(id)}, [id])
}
如何满足class组件构造函数初始化的功能?
思考下构造函数的本质,在其他代码执行之前的一次性初始化工作。
-即我们要实现的就是,一次性代码执行
我们可以实现useSingleton这样的一次性执行某段代码的自定义hook:
function useSingleton(callback) {const called = useRef(false)if (called.current) returncallback()callback.current = true
}
在一个函数组件中,可以调用这个自定义hook来执行一些一次性的初始化逻辑
const myComp = () => {useSingleton(() => {console.log('这段代码只执行一次')})return (<div>...</div>)
}
对于三种常用的生命周期方法
componentDidMount、componentDidUpdate、componentWillUnmount
useEffect(() => {console.log('这里基本等价于componentDidMount + componentDidUpdate')return () => {console.log('这里基本等价于componentWillUnmount')}
}, [deps])