React
adalah sebuah library JavaScript yang di buat oleh facebook
. React bukanlah sebuah framework MVC (Model View Controler). React adalah library yang bersifat composable user interface
, dimana dapat membuat berbagai UI
yang bisa kita bagi menjadi beberapa komponen.
Array
1. DataList
Memberikan daftar elemen dari array primitif.
- Gunakan nilai prop
isOrdered
untuk membuat daftar<ol>
atau<ul>
dengan syarat. - Gunakan
Array.prototype.map
untuk merender setiap item dalamdata
sebagai elemen<li>
, berikankey
yang dihasilkan dari gabungan indeks dan nilainya. - Hilangkan
isOrdered
prop yang dipesan untuk merender daftar<ul>
secara default.
function DataList({ isOrdered, data }) {
const list = data.map((val, i) => <li key={`${i}_${val}`}>{val}</li>);
return isOrdered ? <ol>{list}</ol> : <ul>{list}</ul>;
}
Contoh
const names = ['John', 'Paul', 'Mary'];
ReactDOM.render(<DataList data={names} />, document.getElementById('root'));
ReactDOM.render(<DataList data={names} isOrdered />, document.getElementById('root'));
2. DataTable
Membuat tabel dengan baris yang dibuat secara dinamis dari array primitif.
Render elemen <table>
dengan dua kolom (ID
dan Value
).
Gunakan Array.prototype.map
untuk membuat setiap item dalam data
sebagai elemen <tr>
, yang terdiri dari indeks dan nilainya, berikan key
yang dihasilkan dari gabungan keduanya.
function DataTable({ data }) {
return (
<table>
<thead>
<tr>
<th>ID</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{data.map((val, i) => (
<tr key={`${i}_${val}`}>
<td>{i}</td>
<td>{val}</td>
</tr>
))}
</tbody>
</table>
);
}
Contoh
const people = ['John', 'Jesse'];
ReactDOM.render(<DataTable data={people} />, document.getElementById('root'));
3. MappedTable
Membuat tabel dengan baris yang dibuat secara dinamis dari array objek dan daftar nama properti.
- Gunakan
Object.keys()
,Array.prototype.filter()
,Array.prototype.includes()
danArray.prototype.reduce()
untuk menghasilkanfilteredData
array, berisi semua objek dengan kunci yang ditentukan dalampropertyNames
. - Render elemen
<table>
dengan satu set kolom yang sama dengan jumlah nilai dipropertyNames
. - Gunakan
Array.prototype.map
untuk merender setiap nilai dalam arraypropertyNames
sebagai elemen<th>
. - Gunakan
Array.prototype.map
untuk membuat setiap objek dalam arrayfilteredData
sebagai elemen<tr>
, yang mengandung<td>
untuk setiapkey
dalam objek.
function MappedTable({ data, propertyNames }) {
let filteredData = data.map(v =>
Object.keys(v)
.filter(k => propertyNames.includes(k))
.reduce((acc, key) => ((acc[key] = v[key]), acc), {})
);
return (
<table>
<thead>
<tr>
{propertyNames.map(val => (
<th key={`h_${val}`}>{val}</th>
))}
</tr>
</thead>
<tbody>
{filteredData.map((val, i) => (
<tr key={`i_${i}`}>
{propertyNames.map(p => (
<td key={`i_${i}_${p}`}>{val[p]}</td>
))}
</tr>
))}
</tbody>
</table>
);
}
Komponen ini tidak berfungsi dengan objek bersarang dan akan pecah jika ada objek bersarang di dalam salah satu properti yang ditentukan di propertyNames
.
Contoh
const people = [
{ name: 'John', surname: 'Smith', age: 42 },
{ name: 'Adam', surname: 'Smith', gender: 'male' }
];
const propertyNames = ['name', 'surname', 'age'];
ReactDOM.render(
<MappedTable data={people} propertyNames={propertyNames} />,
document.getElementById('root')
);
Input Control
1. Input
Merender elemen <input>
yang menggunakan fungsi callback untuk meneruskan nilainya ke komponen induk.
- Gunakan perusakan objek untuk menetapkan default untuk atribut tertentu dari elemen
<input>
. - Render elemen
<input>
dengan atribut yang sesuai dan gunakan fungsicallback
balik dalam aktivitasonChange
untuk meneruskan nilai input ke induk.
function Input({ callback, type = 'text', disabled = false, readOnly = false, placeholder = '' }) {
return (
<input
type={type}
disabled={disabled}
readOnly={readOnly}
placeholder={placeholder}
onChange={({ target: { value } }) => callback(value)}
/>
);
}
Contoh
ReactDOM.render(
<Input type="text" placeholder="Insert some text here..." callback={val => console.log(val)} />,
document.getElementById('root')
);
2. LimitedTextarea
Merender komponen textarea dengan batas karakter.
- Gunakan kait
React.useState()
untuk membuat variabel statuscontent
dan atur nilainya kevalue
. Buat metodesetFormattedContent
, yang memotongcontent
input jika lebih panjang darilimit
. - Gunakan kait
React.useEffect()
untuk memanggil metodesetFormattedContent
pada nilai variabel statuscontent
. - Gunakan
<div>
untuk membungkus elemen<textarea>
dan<p>
yang menampilkan jumlah karakter dan ikat acaraonChange
pada<textarea>
untuk memanggilsetFormattedContent
dengan nilaievent.target.value
.
function LimitedTextarea({ rows, cols, value, limit }) {
const [content, setContent] = React.useState(value);
const setFormattedContent = text => {
text.length > limit ? setContent(text.slice(0, limit)) : setContent(text);
};
React.useEffect(() => {
setFormattedContent(content);
}, []);
return (
<div>
<textarea
rows={rows}
cols={cols}
onChange={event => setFormattedContent(event.target.value)}
value={content}
/>
<p>
{content.length}/{limit}
</p>
</div>
);
}
Contoh
ReactDOM.render(<LimitedTextarea limit={32} value="Hello!" />, document.getElementById('root'));
3. LimitedWordTextarea
Merender komponen teks dengan batas kata.
- Gunakan kait
React.useState()
untuk membuat variabel status konten danwordCount
dan atur nilainya masing-masing kevalue
dan0
. - Buat metode
setFormattedContent
, yang menggunakanString.prototype.split('')
untuk mengubah input menjadi array kata dan memeriksa apakah hasil penerapanArray.prototype.filter(Boolean)
memiliki panjang lebih dari batas. - Jika panjang tersebut melebihi batas, pangkas input, jika tidak kembalikan input mentah, perbarui konten dan
wordCount
sesuai dalam kedua kasus. - Gunakan kait
React.useEffect()
untuk memanggil metodesetFormattedContent
pada nilai variabel status konten. - Gunakan
<div>
untuk membungkus elemen<textarea>
dan<p>
yang menampilkan jumlah karakter dan ikat acaraonChange
pada<textarea>
untuk memanggilsetFormattedContent
dengan nilaievent.target.value
.
function LimitedWordTextarea({ rows, cols, value, limit }) {
const [content, setContent] = React.useState(value);
const [wordCount, setWordCount] = React.useState(0);
const setFormattedContent = text => {
let words = text.split(' ');
if (words.filter(Boolean).length > limit) {
setContent(
text
.split(' ')
.slice(0, limit)
.join(' ')
);
setWordCount(limit);
} else {
setContent(text);
setWordCount(words.filter(Boolean).length);
}
};
React.useEffect(() => {
setFormattedContent(content);
}, []);
return (
<div>
<textarea
rows={rows}
cols={cols}
onChange={event => setFormattedContent(event.target.value)}
value={content}
/>
<p>
{wordCount}/{limit}
</p>
</div>
);
}
Contoh
ReactDOM.render(
<LimitedWordTextArea limit={5} value="Hello there!" />,
document.getElementById('root')
);
4. MultiselectCheckbox
Memberikan daftar kotak centang yang menggunakan fungsi panggilan balik untuk meneruskan nilai / nilainya yang dipilih ke komponen induk.
- Gunakan
React.setState()
untuk membuat variabel status data dan menetapkan nilai awalnya sama dengan prop opsi. - Buat toggle fungsi yang digunakan untuk mengaktifkan diperiksa untuk memperbarui variabel status data dan memanggil panggilan balik onChange diteruskan melalui alat peraga komponen.
- Render elemen
<ul>
dan gunakanArray.prototype.map()
untuk memetakan variabel status data ke masing-masing elemen<li>
dengan elemen<input>
sebagai anak-anak mereka. - Setiap elemen
<input>
memiliki atributtype = 'checkbox'
dan ditandai sebagaireadOnly
, karena peristiwa kliknya ditangani oleh handler onClick elemen<li>
induk.
const style = {
listContainer: {
listStyle: 'none',
paddingLeft: 0
},
itemStyle: {
cursor: 'pointer',
padding: 5
}
};
function MultiselectCheckbox({ options, onChange }) {
const [data, setData] = React.useState(options);
const toggle = item => {
data.map((_, key) => {
if (data[key].label === item.label) data[key].checked = !item.checked;
});
setData([...data]);
onChange(data);
};
return (
<ul style={style.listContainer}>
{data.map(item => {
return (
<li key={item.label} style={style.itemStyle} onClick={() => toggle(item)}>
<input readOnly type="checkbox" checked={item.checked || false} />
{item.label}
</li>
);
})}
</ul>
);
}
Contoh
const options = [{ label: 'Item One' }, { label: 'Item Two' }];
ReactDOM.render(
<MultiselectCheckbox
options={options}
onChange={data => {
console.log(data);
}}
/>,
document.getElementById('root')
);
5. PasswordRevealer
Memberikan bidang input kata sandi dengan tombol mengungkapkan.
- Gunakan kait
React.useState()
untuk membuat variabel status yang ditampilkan dan set nilainya menjadifalse
. - Gunakan
<div>
untuk membungkus elemen<input>
dan<button>
yang mengubah jenis bidang input antara"text"
dan"password"
.
function PasswordRevealer({ value }) {
const [shown, setShown] = React.useState(false);
return (
<div>
<input type={shown ? 'text' : 'password'} value={value} onChange={() => {}} />
<button onClick={() => setShown(!shown)}>Show/Hide</button>
</div>
);
}
Contoh
ReactDOM.render(<PasswordRevealer />, document.getElementById('root'));
6. Select
Merender elemen <select>
yang menggunakan fungsi callback untuk meneruskan nilainya ke komponen induk.
- Gunakan perusakan objek untuk menetapkan default untuk atribut tertentu dari elemen
<select>
. - Render elemen
<select>
dengan atribut yang sesuai dan gunakan fungsicallback
di event onChange untuk meneruskan nilai textarea ke induk. - Gunakan destrrukturisasi pada array nilai untuk melewatkan array nilai dan elemen teks dan atribut yang dipilih untuk menentukan nilai awal elemen
<select>
.
function Select({ values, callback, disabled = false, readonly = false, selected }) {
return (
<select
disabled={disabled}
readOnly={readonly}
onChange={({ target: { value } }) => callback(value)}
>
{values.map(([value, text]) => (
<option selected={selected === value} value={value}>
{text}
</option>
))}
</select>
);
}
Contoh
let choices = [
['grapefruit', 'Grapefruit'],
['lime', 'Lime'],
['coconut', 'Coconut'],
['mango', 'Mango']
];
ReactDOM.render(
<Select values={choices} selected="lime" callback={val => console.log(val)} />,
document.getElementById('root')
);
7. Slider
Membuat elemen slider yang menggunakan fungsi callback untuk meneruskan nilainya ke komponen induk.
- Gunakan perusakan objek untuk menetapkan default untuk atribut tertentu dari elemen
<input>
. - Render elemen
<input>
dengan tipe"range"
dan atribut yang sesuai, gunakan fungsicallback
di eventonChange
untuk meneruskan nilai input ke induk.
function Slider({ callback, disabled = false, readOnly = false }) {
return (
<input
type="range"
disabled={disabled}
readOnly={readOnly}
onChange={({ target: { value } }) => callback(value)}
/>
);
}
Contoh
ReactDOM.render(<Slider callback={val => console.log(val)} />, document.getElementById('root'));
8. TextArea
Merender elemen <textarea>
yang menggunakan fungsi callback untuk meneruskan nilainya ke komponen induk.
- Gunakan perusakan objek untuk menetapkan default untuk atribut tertentu dari elemen
<textarea>
. - Render elemen
<textarea>
dengan atribut yang sesuai dan gunakan fungsi panggil balik dalam aktivitasonChange
untuk meneruskan nilai textarea ke induk.
function TextArea({
callback,
cols = 20,
rows = 2,
disabled = false,
readOnly = false,
placeholder = ''
}) {
return (
<textarea
cols={cols}
rows={rows}
disabled={disabled}
readOnly={readOnly}
placeholder={placeholder}
onChange={({ target: { value } }) => callback(value)}
/>
);
}
Contoh
ReactDOM.render(
<TextArea placeholder="Insert some text here..." callback={val => console.log(val)} />,
document.getElementById('root')
);
Object
TreeView
Memberikan tampilan hierarki objek atau array JSON dengan konten yang dapat dilipat.
- Gunakan perusakan objek untuk menetapkan default untuk alat peraga tertentu.
- Gunakan nilai
toggled
prop untuk menentukan keadaan awal konten (diciutkan / diperluas). - Gunakan kait
React.setState()
untuk membuat variabel statusisToggled
dan berikan nilai proptoggled
pada awalnya. - Kembalikan
<div>
untuk membungkus konten komponen dan elemen<span>
, yang digunakan untuk mengubah statusisToggled
komponen. - Tentukan penampilan komponen, berdasarkan
isParentToggled
,isToggled
,name
danArray.isArray()
padadata
. - Untuk setiap anak dalam
data
, tentukan apakah itu objek atau array dan secara render membuat sub-pohon. - Jika tidak, render elemen
<p>
dengan gaya yang sesuai.
.tree-element {
margin: 0;
position: relative;
}
div.tree-element:before {
content: '';
position: absolute;
top: 24px;
left: 1px;
height: calc(100% - 48px);
border-left: 1px solid gray;
}
.toggler {
position: absolute;
top: 10px;
left: 0px;
width: 0;
height: 0;
border-top: 4px solid transparent;
border-bottom: 4px solid transparent;
border-left: 5px solid gray;
cursor: pointer;
}
.toggler.closed {
transform: rotate(90deg);
}
.collapsed {
display: none;
}
function TreeView({
data,
toggled = true,
name = null,
isLast = true,
isChildElement = false,
isParentToggled = true
}) {
const [isToggled, setIsToggled] = React.useState(toggled);
return (
<div
style={{ marginLeft: isChildElement ? 16 : 4 + 'px' }}
className={isParentToggled ? 'tree-element' : 'tree-element collapsed'}
>
<span
className={isToggled ? 'toggler' : 'toggler closed'}
onClick={() => setIsToggled(!isToggled)}
/>
{name ? <strong> {name}: </strong> : <span> </span>}
{Array.isArray(data) ? '[' : '{'}
{!isToggled && '...'}
{Object.keys(data).map((v, i, a) =>
typeof data[v] == 'object' ? (
<TreeView
data={data[v]}
isLast={i === a.length - 1}
name={Array.isArray(data) ? null : v}
isChildElement
isParentToggled={isParentToggled && isToggled}
/>
) : (
<p
style={{ marginLeft: 16 + 'px' }}
className={isToggled ? 'tree-element' : 'tree-element collapsed'}
>
{Array.isArray(data) ? '' : <strong>{v}: </strong>}
{data[v]}
{i === a.length - 1 ? '' : ','}
</p>
)
)}
{Array.isArray(data) ? ']' : '}'}
{!isLast ? ',' : ''}
</div>
);
}
Contoh
let data = {
lorem: {
ipsum: 'dolor sit',
amet: {
consectetur: 'adipiscing',
elit: [
'duis',
'vitae',
{
semper: 'orci'
},
{
est: 'sed ornare'
},
'etiam',
['laoreet', 'tincidunt'],
['vestibulum', 'ante']
]
},
ipsum: 'primis'
}
};
ReactDOM.render(<TreeView data={data} name="data" />, document.getElementById('root'));
String
AutoLink
Merender string sebagai plaintext, dengan URL yang dikonversi ke elemen <a>
yang sesuai.
- Gunakan
String.prototype.split()
danString.prototype.match()
dengan ekspresi reguler untuk menemukan URL dalam sebuah string. - Kembalikan
<React.Fragment>
dengan URL yang cocok yang diberikan sebagai<a>
elemen, berurusan dengan awalan protokol yang hilang jika perlu, dan sisa string yang diterjemahkan sebagai plaintext.
function AutoLink({ text }) {
const delimiter = /((?:https?:\/\/)?(?:(?:[a-z0-9]?(?:[a-z0-9\-]{1,61}[a-z0-9])?\.[^\.|\s])+[a-z\.]*[a-z]+|(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})(?::\d{1,5})*[a-z0-9.,_\/~#&=;%+?\-\\(\\)]*)/gi;
return (
<React.Fragment>
{text.split(delimiter).map(word => {
let match = word.match(delimiter);
if (match) {
let url = match[0];
return <a href={url.startsWith('http') ? url : `http://${url}`}>{url}</a>;
}
return word;
})}
</React.Fragment>
);
}
Contoh
ReactDOM.render(
<AutoLink text="foo bar baz http://example.org bar" />,
document.getElementById('root')
);