react 中的一些细节知识点:
1, 组件中 get 的使用 (作为类的 getter)
ES6 知识: class 类也有自己的 getter 和 setter, 写法如下:
- Class Component {
- constructor() {
- super()
- this.name = ''
- }
- // name 的 getter
- get name() {
- ...
- }
- // name 的 setter
- set name(value) {
- ...
- }
- }
react 组件中的 get 的使用如下:
- /*
- * renderFullName 的 getter
- * 可以直接在 render 中使用 this.renderFullName
- */
- get renderFullName () {
- return `${this.props.firstName} ${this.props.lastName}`;
- }
- render() {
- return (
- <div>{this.renderFullName}</div>
- )
- }
那 getter 在 react 组件中有什么用处呢??
- constructor (props) {
- super()
- this.state = {};
- }
- render () {
- // 常规写法, 在 render 中直接计算
- var fullName = `${this.props.firstName} ${this.props.lastName}`;
- return (
- <div>
- <h2>{fullName}</h2>
- </div>
- );
- }
- // 较为优雅的写法:, 减少 render 函数的臃肿
- renderFullName () {
- return `${this.props.firstName} ${this.props.lastName}`;
- }
- render () {
- var fullName = this.renderFullName()
- <div>{ fullName }</div>
- }
- // 推荐的做法: 通过 getter 而不是函数形式, 减少变量
- get renderFullName () {
- return `${this.props.firstName} ${this.props.lastName}`;
- }
- render () {
- <div>{ this.renderFullName }</div>
- }
如果你了解 vue 的话, 那么你知道其中的 computed: {} 计算属性, 它的底层也是使用了 getter, 只不过是对象的 getter 不是类的 getter
- // 计算属性, 计算 renderFullName
- computed: {
- renderFullName: () => {
- return `${this.firstName} ${this.lastName}`;
- }
- }
Vue 的 computed 有一个优势就是:
计算属性对比函数执行: 会有缓存, 减少计算 ---> 计算属性只有在它的相关依赖发生改变时才会重新求值.
这就意味着只要 firstName 和 lastName 还没有发生改变, 多次访问 renderFullName 计算属性会立即返回之前的计算结果, 而不必再次执行函数.
那么是否 react 的 getter 也有缓存这个优势吗??? 答案是: 没有, react 中的 getter 并没有做缓存优化!
2, 组件的 attr 及事件执行顺序:
A, 父子组件: 以 props 形式, 父传递给子
B, 同一组件: 后面覆盖前面.
依靠上述规则, 那么要使得 attr 的权重最高, 应该放到最底层的组件中, 而且位置尽量的靠后.
- <-- 父组件 Parent | 调用子组件并传递 onChange 属性 -->
- <div>
- <Child onChange={this.handleParentChange} />
- </div>
- <-- 子组件 Child | 接收父组件 onChange, 自己也有 onChange 属性 -->
- <input {...this.props} onChange={this.handleChildChange} />
此时, Child 组件执行的 onChange 只是执行 handleChildChange 事件, handleParentChange 事件并不会执行.
1. 如果只需要执行 handleParentChange 怎么办?? input 中 {...this.props} 与
onChange={this.handleChildChange} 换个位置.
2. 如果两个事件都需要执行怎么办?? 在 Child 组件中 handleChildChange 中执行 this.props.handleParentChange
3, 类中的方法用 ES6 形式简写的不同之处: fn = () => {} 与 fn() {} 的区别:
- export default Class Child extends Component {
- constructor (props) {
- super()
- this.state = {};
- }
- // 写法 1, 这是 ES6 的类的方法写法
- fn1() {
- console.log(this)
- // 输出 undefined
- }
- // 写法 2, 这是 react 的方法写法
- fn2 = () => {
- console.log(this)
- // 输出: Child {props: {...}, context: {...}, refs: {...}, ...}
- }
- render () {
- return (
- <div>
- <button onClick={this.fn1}>fn1 方法执行 </button>
- <button onClick={this.fn2}>fn2 方法执行 </button>
- </div>
- );
- }
- }
可见两种写法, 函数内的 this 指向时不同的.
那它们就没有相同之处吗??, 以下三种情况是相同的:
情况 1: 函数内部用不到 this 的时候, 两者相等.
- // 写法 1, 这是 ES6 的类的方法写法
- fn1() {
- return 1 + 1
- }
- // 写法 2, 这是 react 的方法写法
- fn2 = () => {
- return 1 + 1
- }
情况 2: 两者在 render 中直接执行的时候.
- // 写法 1, 这是 ES6 的类的方法写法
- fn1() {
- console.log(this)
- // Child {props: {...}, context: {...}, refs: {...}, ...}
- }
- // 写法 2, 这是 react 的方法写法
- fn2 = () => {
- console.log(this)
- // 输出: Child {props: {...}, context: {...}, refs: {...}, ...}
- }
- render () {
- return (
- <div>
- <button onClick={() => {
- this.fn1();
- }}>fn1 方法执行 </button>
- <button onClick={() => {
- this.fn2();
- }}>fn2 方法执行 </button>
- </div>
- );
- }
情况 3: 给 this.fn2.bind(this), 绑定 this 作用上下文.
- // 写法 1, 这是 ES6 的类的方法写法
- fn1() {
- console.log(this)
- // Child {props: {...}, context: {...}, refs: {...}, ...}
- }
- // 写法 2, 这是 react 的方法写法
- fn2 = () => {
- console.log(this)
- // 输出: Child {props: {...}, context: {...}, refs: {...}, ...}
- }
- render () {
- return (
- <div>
- <button onClick={this.fn1}>fn1 方法执行 </button>
- <button onClick={this.fn2.bind(this)}>fn2 方法执行 </button>
- </div>
- );
- }
注意, 不要和 ES6 中对象的方法简写弄混了, 以下是对象 Obeject 的方法简写:
阮一峰 ES6: http://es6.ruanyifeng.com/#docs/object
来源: https://www.cnblogs.com/faith3/p/9219448.html