使用react的7個(gè)避坑案例

React是個(gè)很受歡迎的前端框架。今天我們探索下React開發(fā)者應(yīng)該注意的七個(gè)點(diǎn)。
1. 組件臃腫
React開發(fā)者沒有創(chuàng)建必要的足夠多的組件化,其實(shí)這個(gè)問(wèn)題不局限于React開發(fā)者,很多Vue開發(fā)者也是。
當(dāng)然,我們現(xiàn)在討論的是React
在React中,我們可以創(chuàng)建一個(gè)很多內(nèi)容的組件,來(lái)執(zhí)行我們的各種任務(wù),但是最好是保證組件精簡(jiǎn) -- 一個(gè)組件關(guān)聯(lián)一個(gè)函數(shù)。這樣不僅節(jié)約你的時(shí)間,而且能幫你很好地定位問(wèn)題。
比如下面的TodoList組件:
// ./components/TodoList.js
import React from 'react';
import { useTodoList } from '../hooks/useTodoList';
import { useQuery } from '../hooks/useQuery';
import TodoItem from './TodoItem';
import NewTodo from './NewTodo';
const TodoList = () => {
const { getQuery, setQuery } = useQuery();
const todos = useTodoList();
return (
<div>
<ul>
{todos.map(({ id, title, completed }) => (
<TodoItem key={id} id={id} title={title} completed={completed} />
))}
<NewTodo />
</ul>
<div>
Highlight Query for incomplete items:
<input value={getQuery()} onChange={e => setQuery(e.target.value)} />
</div>
</div>
);
};
export default TodoList;
2. 直接更改state
在React中,狀態(tài)應(yīng)該是不變的。如果你直接修改state,會(huì)導(dǎo)致難以修改的性能問(wèn)題。
比如下面例子:
const modifyPetsList = (element, id) => {
petsList[id].checked = element.target.checked;
setPetsList(petList)
}
上面例子中,你想更改數(shù)組對(duì)象中checked鍵。但是你遇到一個(gè)問(wèn)題:因?yàn)槭褂孟嗤囊酶牧藢?duì)象,React無(wú)法觀察并觸發(fā)重新渲染。
解決這個(gè)問(wèn)題,我們應(yīng)該使用setState()方法或者useState()鉤子。
我們使用useState()方法來(lái)重寫之前的例子。
const modifyPetsList = (element, id) => {
const { checked } = element.target;
setpetsList((pets) => {
return pets.map((pet, index) => {
if (id === index) {
pet = { ...pet, checked };
}
return pet;
});
});
};
3. props該傳數(shù)字類型的值卻傳了字符串,反之亦然
這是個(gè)很小的錯(cuò)誤,不應(yīng)該出現(xiàn)。
比如下面的例子:
class Arrival extends React.Component {
render() {
return (
<h1>
Hi! You arrived {this.props.position === 1 ? "first!" : "last!"} .
</h1>
);
}
}
這里===對(duì)字符串'1'是無(wú)效的。而解決這個(gè)問(wèn)題,需要我們?cè)趥鬟fprops值的時(shí)候用{}包裹。
修正如下:
// ?
const element = <Arrival position='1' />;
// ?
const element = <Arrival position={1} />;
4. list組件中沒使用key
假設(shè)我們需要渲染下面的列表項(xiàng):
const lists = ['cat', 'dog', 'fish’];
render() {
return (
<ul>
{lists.map(listNo =>
<li>{listNo}</li>)}
</ul>
);
}
當(dāng)然,上面的代碼可以運(yùn)行。當(dāng)列表比較龐雜并需要進(jìn)行更改等操作的時(shí)候,就會(huì)帶來(lái)渲染的問(wèn)題。
React跟蹤文檔對(duì)象模型(DOM)上的所有列表元素。沒有記錄可以告知React,列表發(fā)生了什么改動(dòng)。
解決這個(gè)問(wèn)題,你需要添加keys在你的列表元素中。keys賦予每個(gè)元素唯一標(biāo)識(shí),這有助于React確定已添加,刪除,修改了哪些項(xiàng)目。
如下:
<ul>
{lists.map(listNo =>
<li key={listNo}>{listNo}</li>)}
</ul>
5. setState是異步操作
很容易忘記React中的state是異步操作的。如果你在設(shè)置一個(gè)值之后就去訪問(wèn)它,那么你可能不能立馬獲取到該值。
我們看看下面的例子:
handlePetsUpdate = (petCount) => {
this.setState({ petCount });
this.props.callback(this.state.petCount); // Old value
};
你可以使用setState()的第二個(gè)參數(shù),回調(diào)函數(shù)來(lái)處理。比如:
handlePetsUpdate = (petCount) => {
this.setState({ petCount }, () => {
this.props.callback(this.state.petCount); // Updated value
});
};
6. 頻繁使用Redux
在大型的React app中,很多開發(fā)者使用Redux來(lái)管理全局狀態(tài)。
雖然Redux很有用,但是沒必要使用它來(lái)管理每個(gè)狀態(tài)。
如果我們的應(yīng)用程序沒有需要交換信息的并行級(jí)組件的時(shí)候,那么就不需要在項(xiàng)目中添加額外的庫(kù)。比如我們想更改組件中的表單按鈕狀態(tài)的時(shí)候,我們更多的是優(yōu)先考慮state方法或者useState鉤子。
7. 組件沒以大寫字母開頭命名
在JSX中,以小寫開頭的組件會(huì)向下編譯為HTML元素。
所以我們應(yīng)該避免下面的寫法:
class demoComponentName extends React.Component {
}
這將導(dǎo)致一個(gè)錯(cuò)誤:如果你想渲染React組件,則需要以大寫字母開頭。
那么得采取下面這種寫法:
class DemoComponentName extends React.Component {
}
原文地址
https://juejin.cn/post/6963032224316784654
