一、React 生命周期
1、生命周期简介
React 生命周期是指 React 组件从实例创建到销毁的整个过程。其中包含挂载、更新和卸载三个阶段。
2、生命周期分类
React 生命周期可以分为三类:Mounting, Updating, Unmounting。其中 Mounting 指组件加载到 DOM 上,Update 指组件数据改变引起的重新渲染,Unmounting 指组件卸载销毁时。
3、常用生命周期
componentDidMount():组件挂载时调用,可以进行 AJAX 请求和 DOM 操作等。
componentDidUpdate():组件更新时调用,可以进行更新操作。
componentWillUnmount():组件卸载时调用,可以进行一些清理操作。
二、React 的虚拟 DOM
1、什么是虚拟 DOM
虚拟 DOM 是简化版的 DOM,是 React 中组件状态改变后重新渲染组件的关键技术。虚拟 DOM 通过一系列的比较和更新操作,尽可能地减少与真实 DOM 的交互,从而提高页面渲染效率。
2、虚拟 DOM 的优点
(1)提高页面渲染效率,避免了每次修改都涉及到真实 DOM 的操作;
(2)简化了操作,提升了开发效率;
(3)实现了 diff 算法,可以最小化更新 DOM,从而提高了页面性能。
三、React 组件间通信
1、组件间通信方式
(1)props 静态方式:通过 props 把数据从父组件传递到子组件。
(2)context 跨级方式:通过 context 属性可以在组件树中直接传递数据,跨级传递更加便捷。
(3)自定义事件方式:通过自定义事件向祖先或子孙组件传递信息。
2、props 与 state 的区别
(1)props 是父组件向子组件传递的数据;state 是组件自己的状态数据。
(2)props 是只读的,不允许子组件修改;state 可以由组件自己修改,但需要通过 setState() 方法改变。
四、React 高阶组件(HOC)
1、高阶组件简介
高阶组件是指将一个组件作为参数,并返回一个新组件的函数。
2、高阶组件的作用
(1)代码复用:将多个组件公用的逻辑抽取成一个高阶组件,避免代码冗余;
(2)扩展组件功能:将某个组件需要的功能通过高阶组件注入的方式进行扩展;
(3)渲染劫持:在不修改组件本身的前提下对组件进行渲染控制。
3、高阶组件示例代码:
// HOC const withLoginStatus = (WrappedComponent) => { return class extends React.Component { constructor(props) { super(props); this.state = { isLoggedIn: false }; } componentDidMount() { this.setState({ isLoggedIn: true }); } render() { const { isLoggedIn } = this.state; return; } } } // 组件 const MyComponent = ({ isLoggedIn }) => ( {isLoggedIn ? '您已登录' : '请登录'}
); // 使用 const WrappedComponent = withLoginStatus(MyComponent); ReactDOM.render(, document.getElementById('app'));
五、React 的性能优化
1、虚拟 DOM 优化
(1)减少不必要的渲染:通过 shouldComponentUpdate() 方法来控制是否需要重新渲染组件。
(2)合理使用 React.Fragment:减少多余的 DOM 包裹标签。
(3)使用 key 属性:相同的 key 值可以减少虚拟 DOM 比对时的计算量。
2、其他性能优化
(1)使用 React 生产环境构建:生产环境构建时可以去除开发环境下的调试代码和警告信息。
(2)避免过量渲染:尽可能减少 DOM 操作次数。
(3)优化 JavaScript 代码:避免使用循环嵌套等性能开销大的操作。
代码示例:
class MyComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { if (this.props.text === nextProps.text && this.state.count === nextState.count) { return false; } return true; } render() { return ( <React.Fragment> <span key="text">{this.props.text}</span> <button key="btn">{this.state.count}</button> </React.Fragment> ); } }
六、Redux 与 React 结合
1、Redux 基本用法
(1)Action:定义数据操作的类型。
(2)Reducer:定义数据操作,并返回操作后的新数据。
(3)Store:用于管理应用的 State。
2、Redux 与 React 结合示例代码:
// Action const ADD_TODO = 'ADD_TODO'; const REMOVE_TODO = 'REMOVE_TODO'; // Action Creator const addTodo = (text) => ({ type: ADD_TODO, payload: { text, }, }); const removeTodo = (id) => ({ type: REMOVE_TODO, payload: { id, }, }); // Reducer const todos = (state = [], action) => { switch (action.type) { case ADD_TODO: return [...state, action.payload.text]; case REMOVE_TODO: return state.filter((item, index) => index !== action.payload.id); default: return state; } }; // Store const store = createStore(todos); // React 组件 const TodoList = ({ todos }) => ( <ul> {todos.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); class TodoApp extends React.Component { constructor(props) { super(props); this.state = { todos: store.getState() }; this.handleAdd = this.handleAdd.bind(this); this.handleRemove = this.handleRemove.bind(this); } componentDidMount() { this.unsubscribe = store.subscribe(() => { this.setState({ todos: store.getState() }); }); } componentWillUnmount() { this.unsubscribe(); } handleAdd() { const text = prompt('请输入待办事项'); if (text) { store.dispatch(addTodo(text)); } } handleRemove(index) { store.dispatch(removeTodo(index)); } render() { const { todos } = this.state; return ( <React.Fragment> <TodoList todos={todos} /> <button onClick={this.handleAdd}>新增</button> </React.Fragment> ); } } ReactDOM.render(<TodoApp />, document.getElementById('app'));