什麼是 JSX?#
JSX
是 js 的語法擴展,允許在 js 中編寫 html 代碼,是 2013 年 伴隨 React 庫的首次發布而出現,並簡化了用戶界面的開發過程和提高代碼的可讀性及維護性
例如🌰
// 不使用 JSX 的 React 代碼
const element = React.createElement('h1', { className: 'title' }, 'Hello, world!');
// 使用 JSX 的 React 代碼
const element = <h1 className="title">Hello, world!</h1>;
Tip
JSX 比 HTML 更加嚴格。你必須閉合標籤,如 <br />。你的組件也不能返回多個 JSX 標籤。你必須將它們包裹到一個共享的父級中,比如 <div>...</div> 或使用空的 <>...</> 包裹:
function Hello() {
return (
<>
<h1>Hello, world!</h1>
</>
);
}
在 JSX 中嵌入表達式#
const name = '張三';
const fn = () => alert('fn函數')
const App = () => {
return (
<>
<h1>{ name }</h1>
<button>{ fn() }</button>
<p>{ new Date().toLocaleString() }</p>
</>
);
};
在 JSX 中添加屬性#
Warning
由於 JSX 比 HTML 更接近 JavaScript,因此 React DOM 使用駝峰式屬性命名約定而不是 HTML 屬性名稱。
例如,class
在 JSX 中變為 className
,tabindex
變為 tabIndex。
const user = {
className: 'avatar-img',
imageUrl: 'https://www.gravatar.com/avatar/0?d=mp',
style: {
border: '2px solid red',
borderRadius: '50%',
}
}
const App = () => {
return (
<>
<img src={ user.imageUrl } className={ user.className } style={user.style} alt="頭像" />
</>
);
};
在 JSX 中綁定事件#
使用 tsx 綁定事件 on[Click]{ fn }
小駝峰 其他事件也是一樣的。如果需要傳遞參數可以使用 on[Click]{ () => fn() }
const clickFn = (name) => {
console.log('clicked', name);
}
const mouseEnterFn = () => {
console.log('mouse entered');
}
const mouseLeaveFn = () => {
console.log('mouse leveled');
}
const App = () => {
return (
<>
<h1>Hello, world!</h1>
<button onClick={() => clickFn('button')} onMouseEnter={mouseEnterFn} onMouseLeave={mouseLeaveFn}>點擊我</button>
</>
);
};
在 JSX 中條件渲染#
const flag = true;
const App = () => {
return (
<>
<div>{ flag ? <div>真的</div> : <div>假的</div> }</div>
</>
);
};
當你不需要 else 分支時,你也可以使用更簡短的 邏輯 && 語法:
<div>
{isLoggedIn && <AdminPanel />}
</div>
更複雜的判斷邏輯可以寫在一個函數裡面
const messageTip = (code) => {
switch (code) {
case 200:
return <div className="message-tip success">成功</div>;
case 404:
return <div className="message-tip error">錯誤</div>;
default:
return <div className="message-tip info">資訊</div>;
}
}
const App = () => {
return (
<>
{ messageTip(200) }
</>
);
};
在 JSX 中遍歷元素#
使用 map 遍歷返回 html 標籤
const userList = [
{ id: 1, name: '張三', age: 18, gender: '男' },
{ id: 2, name: '李四', age: 19, gender: '女' },
{ id: 3, name: '王五', age: 20, gender: '男' },
{ id: 4, name: '趙六', age: 21, gender: '女' },
{ id: 5, name: '錢七', age: 22, gender: '男' },
{ id: 6, name: '孫八', age: 23, gender: '女' },
{ id: 7, name: '周九', age: 24, gender: '男'},
]
const App = () => {
return (
<>
{ userList.filter(user => user.age > 20).map(user => <div key={user.id}>{user.name}</div>) }
</>
);
};
在 JSX 中渲染 html 片段#
Warning
使用 dangerouslySetInnerHTML
後元素不要添加內容,否則會出錯
const App = () => {
return (
<>
<div dangerouslySetInnerHTML={{__html: el}}>{/* 此處留空,否則會報錯 */}</div>
</>
);
};
常見問題#
1、JSX 語句內只能使用表達式、不能使用語句和字面量等
// Error: Objects are not valid as a React child (found: object with keys {key}). If you meant to render a collection of children, use an array instead.
const element = <div>{ { key: 'value' } }</div>;
// ✅
const element = <div>{ JSON.stringify({ key: 'value' }) }</div>;
// ✅
const element = <div>{ { key: 'value' }.key }</div>;
2、TSX 如何使用泛型
正常寫泛型語法會跟 tsx 語法衝突,他會把泛型理解成是一個元素,解決方案後面加一個 ,
即可
const clickTap = <T,>(params: T) => alert(params)
const element = <button onClick={() => clickTap('張三')}>點擊我</button>;