【Day 25】React 与 Immutible

Immutable

Immutable 中文意思为不可变的,
即重新赋值後,
新的值和原始的值并不互相影响
原本的值依然会保留下来,
不会被赋值改变。

Immutable 范例

let str = 'Hello, you!!';
let ianHello = str;
ianHello += 'ian';

// not changed
console.log(str); // Hello, you!!
console.log(ianHello); // Hello, you!!ian

与之相反的是 mutable,
第一次赋值後,
对物件进行如赋值等操作後,
mutable 的内容会产生变化。

Mutable 范例

let names = ['ian'];
let copyName = names;
copyName.push('peter');

// changed
console.log(names); // [ian, peter]
console.log(copyName); // [ian, peter]

而 React 为了避免资源浪费,
会比较元件的 props 和 state 是否有变更,
在无变化的情况下便不会触发 re-render,

因此 state 更新的内容必须是 Immutable,
否则 React 就无法追踪到资料内容的变化,
也就不会触发任何 render。

无法触发 re-render 的范例:

const [state, setState] = useState({
	list: []
})

clickBtn = () => {
  state.list.push({
	id: Math.random(),
	name: randomStr.generate(4)
  });
  setState(state);
};

如上方范例中,
直接修改 state 的 list 阵列内容,
但 state 本身在记忆体中
依然指向同样的参考,
程序并未收到变更讯息,
所以不会触发 render。


解决方式

ES6 的解构方法

setState({ 
  list: [
    ...state.list,
    { id: Math.random(), name: randomStr.genreate(4) }
  ]
});

把原本的 state 浅拷贝一份出来,
给予不同的记忆体位置後,
就可以正确 render 了。


使用辅助套件

使用 Object.assign 或是 es6 解构的时候只能对第一层拷贝,如果有多层资料时,里面的东西就不会被拷贝到,依然是原本物件储存的参考,这时一样无法触发 render。

const a = { b: { c: 1344 } };
const b = {...a);
b.b.c = 2000;
console.log(a.b.c) //2000

以下列出一些在改变 state 时,
能轻松达成 Immutable 的辅助套件。


参考资料


<<:  Day 28 | 状态管理-从官方范例来看如何使用BLoC

>>:  Youtube Analytics API 教学 - 告一个段落

.NET Core第21天_FormTagHelper的使用_防止跨站请求设置方式

FormTagHelper : 为.net对html原生的封装, 预设若没指定method则是采用g...

[Day24] Scrum 的交付与迭代迷思

「Scrum 说每个 Sprint 结束,都应该有可以使用的新功能释出,如果一个 Story 在一个...

DAY 13 Big Data 5Vs – Variety(速度) Glue(1) Crawler

轻巧有弹性的Lambda能解决转档、压缩等简单的处理运算,然而在AWS上如果要建立基本完整的ETL流...

# Day 10 Cache and TLB Flushing Under Linux (二)

那麽接续昨天的阅读,我们继续看下去~ 文件 文件原文:Cache and TLB Flushing ...

Day15 Pseudo Element 眼见不一定为真

什麽是伪元素(Pseudo Element)? 伪元素就如同它的名字一样,不是一个实际存在於网页里...