介紹
最近在重讀React官方文檔,盤點一些不常用但有用的知識點。如果有啥說的不好的地方,歡迎指正!
推薦個翻譯的不錯的React文檔
getSnapshotBeforeUpdate()
getSnapshotBeforeUpdate()
爲React生命週期函數, 在render()
之前調用。它使得組件能在發生更改之前從 DOM 中捕獲一些信息(例如,滾動位置)。此生命週期的任何返回值將作爲參數傳遞給 componentDidUpdate()
。
處理聊天滾動的示例:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// 我們是否在 list 中添加新的 items ?
// 捕獲滾動位置以便我們稍後調整滾動位置。
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// 如果我們 snapshot 有值,說明我們剛剛添加了新的 items,
// 調整滾動位置使得這些新 items 不會將舊的 items 推出視圖。
//(這裏的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
forceUpdate()
默認情況下,當組件的 state
或 props
發生變化時,組件將重新渲染。如果 render() 方法依賴於其他數據,則可以調用 forceUpdate()
強制讓組件重新渲染。
調用 forceUpdate()
將致使組件調用 render()
方法,此操作會跳過該組件的 shouldComponentUpdate()
。但其子組件會觸發正常的生命週期方法,包括 shouldComponentUpdate()
方法。如果標記發生變化,React 仍將只更新 DOM。
簡單來說forceUpdate()方法可以強制
更新組件,所以不建議使用!
key
key顧名思義爲組件的標識,當key改變時組件會重新註冊
!但我們使用最多的還是遍歷!
const todos = [1, 2, 3, 4, 5];
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
其實用index作爲Key有問題,可以看這篇博客
狀態提升
官方解釋:通常,多個組件需要反映相同的變化數據,這時我們建議將共享狀態提升到最近的共同父組件中去。
簡單來說,就是兩個子組件都使用父組件的一個參數,通過props把改參數傳入子組件,並把改變該參數的方法一併傳入子組件,通過調用該方法改變父組件共用的參數!
舉個例子🌰
現在有ComponentA以及ComponentB,他們各有一個輸入框,當我在其中一個輸入框輸入英文單詞時,在另一個組件展示轉換後的大小寫。
class ComponentA extends React.Component {
// 當input輸入時,在另一個組件顯示大的大小寫轉換
handleChange(e) => {
const { onChangeWordUpper } = this.props;
onChangeWordUpper(e.target.value);
};
render() {
const { word } = this.props;
return (
<h2>ComponentA enter: {word}</h2>
<input onChange={this.handleChange} />
);
}
}
class ComponentB extends React.Component {
// 當input輸入時,在另一個組件顯示大的大小寫轉換
handleChange(e) => {
const { onChangeWordLower } = this.props;
onChangeWordLower(e.target.value);
};
render() {
const { word } = this.props;
return (
<h2>ComponentB enter: {word}</h2>
<input onChange={this.handleChange} />
);
}
}
父組件componentFather
class ComponentFather extends React.Component {
state = {
word: '';
}
// 轉換爲大寫
onChangeWordUpper(value) => {
const word = value.toUpperCase()
this.setState({ word });
}
// 轉換爲小寫
onChangeWordLower(value) => {
const word = value.toLowerCase()()
this.setState({ word });
}
render() {
const { word } = this.state;
const componentAProps = {
word,
onChangeWordUpper: this.onChangeWordUpper,
};
const componentBProps = {
word,
onChangeWordUpper: this.onChangeWordLower,
};
return (
<ComponentA {...componentAProps} />
<ComponentB {...componentBProps} />
);
}
}
未完待續