Cũng giống như Javascript, thông thường chúng ta sẽ muốn chia sẻ code với nhau qua các function. Nếu bạn sử dụng JSX bạn cũng có thể chia sẻ và sử dụng lại code. Trong React, chúng ta gọi đó là các functions “components” và chúng có những props đặc biệt khi là một component trong React.
Component đơn giản chỉ là những functions mà nó return về một giá trị đặc biệt có thể render được(React elements, string, null, number, …)
Giả sử bạn có các DOM
<div className="container">
<div className="message">Hello World</div>
<div className="message">Goodbye World</div>
</div>
Trong trường hợp này, bạn có thể viết một functional component trong React để sử dụng lại và tránh lặp code của:
<div className="message">{children}</div>
Cho nên chúng ta cần tạo một hàm nhận vào tham số là children và trả về React element. Và bạn có thể interpolate hàm đó, gọi nó như sau:
<div>{message('Hello World')}</div>
Đây chưa phải là cách để tạo nên custom component trong React nhưng chí ít là bạn hiểu đươc cách tạo function và sử dụng lại nó để tránh việc lặp code.
Đáp án:
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script type="text/babel">
// NOTE: this is NOT being used as a component. We're not quite there yet.
function message({children}) {
return <div className="message">{children}</div>
}
const element = (
<div className="container">
{message({children: 'Hello World'})}
{message({children: 'Goodbye World'})}
</div>
)
ReactDOM.render(element, document.getElementById('root'))
</script>
</body>
Sử dụng custom component với React.createElement.
Bạn có thể sử dụng React.createElement để truyền vào một function component như tham số thứ nhất của React.createElement()
Thay vì gọi hàm message trực tiếp, bạn có thể truyền tham số thứ nhất là hàm message and tham số thứ hai là một object như { children: ‘Hello World’ }
Đáp án:
function message({children}) {
return <div className="message">{children}</div>
}
const element = (
<div className="container">
{React.createElement(message, {children: 'Hello World'})}
{React.createElement(message, {children: 'Goodbye World'})}
</div>
)
ReactDOM.render(element, document.getElementById('root'))
Sử dụng propTypes để check trong runtime
Thay đổi component Message một chút:
function Message({subject, greeting}) {
return (
<div className="message">
{greeting}, {subject}
</div>
)
}
Chúng ta có thể sử dụng component này như sau:
<Message greeting="Hello" subject="World" />
<Message greeting="Goodbye" subject="World" />
Vấn đề gì xảy ra nếu chúng ta quên truyền props cho component Message. Chúng ta có thể get được những error chung chung về component đó, nhưng để rõ ràng hơn bạn nên sử dụng propTypes để check type cho từng props. Khi mà chúng ta truyền type bị sai chúng ta sẽ nhận những thông báo lỗi rõ ràng hơn, tường minh hơn. Điều đo giúp bạn tìm ra lỗi và sửa lỗi nhanh hơn.
Có một điều thú vị là bạn có thể tự định nghĩa propTypes function như sau:
function FavoriteNumber({favoriteNumber}) {
return <div>My favorite number is: {favoriteNumber}</div>
}
const PropTypes = {
number(props, propName, componentName) {
if (typeof props[propName] !== 'number') {
return new Error('Some useful error message here')
}
},
}
FavoriteNumber.propTypes = {
favoriteNumber: PropTypes.number,
}
Thông thường để cho đơn giản, chúng ta sẽ sử dụng package của React propTypes để check type:
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react@17.0.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.12.4/babel.js"></script>
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script type="text/babel">
function Message({subject, greeting}) {
return (
<div className="message">
{greeting}, {subject}
</div>
)
}
Message.propTypes = {
subject: PropTypes.string.isRequired,
greeting: PropTypes.string.isRequired,
}
const element = (
<div className="container">
<Message subject="World" greeting="Hello" />
<Message subject="World" greeting="Goodbye" />
</div>
)
ReactDOM.render(element, document.getElementById('root'))
</script>
</body>
Sử dụng React Fragment
Có một component đăc biệt trong React là React Fragments. Giúp bạn bọc hai hay nhiều component con bên trong là không cần một wrapper như thẻ div. Điều này giúp đơn giản cây DOM và xoá những wrapper dư thừa như thẻ div. Sử dụng như sau:
function Message({subject, greeting}) {
return (
<div className="message">
{greeting}, {subject}
</div>
)
}
Message.propTypes = {
subject: PropTypes.string.isRequired,
greeting: PropTypes.string.isRequired,
}
const element = (
<>
<Message subject="World" greeting="Hello" />
<Message subject="World" greeting="Goodbye" />
</>
)
ReactDOM.render(element, document.getElementById('root'))
thaunguyen.com via Epic React by Kent C.Dodds
tks