为什么 React 需要 Immutable?

关注并将「趣谈前端」设为星标

每天早 08 : 30 按时推送技术干货/优秀开源/技术思维

对⼀个问题的研究,尝试⽤⻩⾦圈法则来分析。

  • Why 为什么 React 需要 immutable

  • How 如何在使⽤ React 使⽤ immutable

  • What 带来的收益和结果

为什么要在React 使⽤ immutable


⼀句话概况: React 使⽤了 shallowCompare 来决定是否应该重新渲染⼀个组件。

要理解 shallowCompare,我们⾸先需要知道 JavaScript 是如何处理对象引⽤的。让我们来看 ⼀个例⼦:

const people = [{ name: "mary", age: 20 }, { name: "john", age: 30 }];
const john = people[1];
const jonhClone = { name: "john", age: 30 };
console.log(john === people[1]) // true
console.log(john === jonhClone) // false
people[1].age = 31;
console.log(john) // { name: "john", age: 31 }
console.log(jonhClone) // { name: "john", age: 30 }

johnClonenameagejohn 相同,但他们不是同⼀个⼈。当我们声明 john = people[1], 我们没有拷⻉ people[1]nameagejohn ,两个变量都指向同⼀个对象作为引⽤。



ShallowCompare

现在我们来看⼀个 shallowCompare的例⼦:

let oldProps = null;
function shallowCompare (props){
 if(props !== oldProps) console.log(props);
 oldProps = props;
}
const mary = { name: "mary", age: 20 };
const john = { name: "john", age: 30 };
shallowCompare(mary) // prints -> { name: "mary", age: 20 }
shallowCompare(john) // prints -> { name: "john", age: 30 }
john.age = 31;
shallowCompare(john) // will not print!

如果我们想打印 john 的更新,我们需要浅拷⻉它。这样⼀来,shallowCompare 就会知道道具发⽣了变化。

let oldProps = null;
function shallowCompare (props){
 if(props !== oldProps) console.log(props);
}
const john = { name: "john", age: 30 };
shallowCompare(john) // prints -> { name: "john", age: 30 }
const johnClone = {...john};
johnClone.age=31;
shallowCompare(johnClone) // prints -> { name: "john", age: 31 }

React 中的例⼦

React 使⽤同样的原则来避免不必要的组件重渲染。

class People extends Component {
 constructor(props) {
   super(props);
   this.state = {
    people:[{ name: "mary", age: 25 }, { name: "john", age: 30 }]
   };
 }
 updateJohnAge = ()=>{
   const people = [...this.state.people];
   people[1].age=31;
   this.setState({people});
   //This will not work.
   //People is a new array, but john is the same object
 }
 render() {
   return (
     <div>
       <Person person={this.state.people[1]}></Person>
       <button onClick={this.updateJohnAge}>Set john age to 31</button>
     </div>
   );
 }
}
class Person extends Component {
 render() {
   const { person } = this.props;
   return (
     <div>
       <p>name: {person.name}</p>
       <p>age: {person.age}</p>
     </div>
    );
  }
}

如果我们点击按钮,组件将不会呈现 john 的更新,因为 people[1] 是上次的同⼀个引⽤。为此,没有改变 john 。我们需要在之前克隆 john ,然后更新数组。

updateJohnAge = () =>{
 const people = [...this.state.people];
 const johnClone = {...people[1]};
 johnClone.age = 31;
 people[1] = johnClone;
 this.setState({people});
 //This will work.
}

要知道,我们并没有拷⻉ people[0] (mary)Immutable 并不意味着我们要详尽地克隆所有对象的 ramifications。这将不会很有效率。我们只需要通过我们改变的路径来创建新的引⽤。

END

如果觉得这篇文章还不错

点击下面卡片关注我的视频号

来个【分享、点赞、在看】三连支持一下吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React 中,我们通常使用 Immutable 数据结构来管理应用的状态。Immutable 是一个不可变的数据结构库,它的主要思想是将数据作为不可变的值来处理,而不是作为可变的对象。 使用 Immutable 的好处是可以避免因为状态的可变性而引起的一些问题,例如在 React 中,当状态发生变化时,如果直接修改状态对象,React 可能无法检测到状态的变化,从而导致组件不会重新渲染。而使用 Immutable 数据结构,我们可以通过创建新的不可变对象来更新状态,从而保证 React 能够正确地检测到状态的变化,并且在需要重新渲染组件时能够及时更新。 Immutable 数据结构通常使用一些特殊的方法来实现不可变性,例如 `set`、`get`、`update` 等方法。使用这些方法可以保证原始数据结构不会被修改,而是返回一个新的不可变对象。例如: ``` import { Map } from 'immutable'; const state = Map({ counter: 0 }); // 创建新的不可变对象 const newState = state.set('counter', state.get('counter') + 1); console.log(state.get('counter')); // 0 console.log(newState.get('counter')); // 1 ``` 在这个例子中,我们使用 Immutable 库中的 `Map` 类创建了一个不可变的状态对象,并通过 `set` 和 `get` 方法来更新和获取状态的值。更新状态时,我们创建了一个新的不可变对象 `newState`,而原始的状态对象 `state` 并没有被修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值