Using React Props: Validation with Dynamic Components and PropTypes
🎯 What Will You Learn in This Guide?
In this guide, you will learn step by step how to customize your components using React Props (attributes), how to pass different data types (string, array, object, function) and how to validate this data with PropTypes.
You will also see how to define safe default values for missing data with defaultProps.
💻 Prerequisites
- Node.js and npm must be installed
- Knowing how to use Create React App
- Mastering JSX syntax and React component structure
1️⃣ Creating and Cleaning a New React Project
Create a new React project:
npx create-react-app genixnode-props-rehberi
cd genixnode-props-rehberi
npm start
With these commands, the development server starts. The project appears at http://localhost:3000.
Simplify the default code. Open src/App.js:
import React from 'react';
import './App.css';
function App() {
return <></>; // Başlangıçta boş bir sayfa
}
export default App;
Delete unused logo file:
rm src/logo.svg
Create component folders for a more organized structure:
mkdir src/components
mkdir src/components/App
mv src/App.* src/components/App
src/index.js dosyasındaki import yolunu güncelleyin:
import App from './components/App/App';
2️⃣ Creating Dynamic Components with Props
📁 Sample Data File (data.js)
Add data.js to src/components/App/ directory:
export default [
{
name: 'Aslan',
scientificName: 'Panthera leo',
size: 140,
diet: ['et'],
},
{
name: 'Goril',
scientificName: 'Gorilla beringei',
size: 205,
diet: ['bitki', 'böcek'],
additional: { notes: 'Bu, doğu gorilidir. Batı gorili farklı bir türdür.' }
},
{
name: 'Zebra',
scientificName: 'Equus quagga',
size: 322,
diet: ['bitki'],
additional: {
notes: 'Üç farklı zebra türü vardır.',
link: 'https://tr.wikipedia.org/wiki/Zebra'
}
}
];
This sample data is a practical example of passing Props on different data types.
🧩 Creating the AnimalCard Component
Create the src/components/AnimalCard/ folder:
mkdir src/components/AnimalCard
touch src/components/AnimalCard/AnimalCard.js
touch src/components/AnimalCard/AnimalCard.css
AnimalCard.js content:
import React from 'react';
import './AnimalCard.css';
export default function AnimalCard() {
return <h2>Hayvan</h2>;
}
🦁 Transferring Data from App Component
Open src/components/App/App.js:
import React from 'react';
import data from './data';
import AnimalCard from '../AnimalCard/AnimalCard';
import './App.css';
function App() {
return (
<div className="wrapper">
<h1>GenixNode Hayvanat Bahçesi</h1>
{data.map(animal => (
<AnimalCard
key={animal.name}
name={animal.name} // Prop olarak veri gönder
/>
))}
</div>
);
}
export default App;
🧠 Using Props Within a Component
Update AnimalCard.js:
import React from 'react';
import './AnimalCard.css';
export default function AnimalCard({ name }) {
return <h2>{name}</h2>;
}
Improves code readability by destructuring { name } instead of props.name.
3️⃣ Passing Multiple Data Types and Function Props
Go back to App.js:
function showAdditional(additional) {
if (!additional) return;
const info = Object.entries(additional)
.map(([k, v]) => `${k}: ${v}`)
.join('\n');
alert(info);
}
function App() {
return (
<div className="wrapper">
<h1>GenixNode Hayvanat Bahçesi</h1>
{data.map(animal => (
<AnimalCard
key={animal.name}
name={animal.name}
scientificName={animal.scientificName}
size={animal.size}
diet={animal.diet}
additional={animal.additional}
showAdditional={showAdditional}
/>
))}
</div>
);
}
Then expand AnimalCard.js:
export default function AnimalCard({
name,
scientificName,
size,
diet,
additional,
showAdditional
}) {
return (
<div className="animal-wrapper">
<h2>{name}</h2>
<h3>{scientificName}</h3>
<h4>{size} kg</h4>
<p>Diyet: {diet.join(', ')}</p>
<button onClick={() => showAdditional(additional)}>Detaylı Bilgi</button>
</div>
);
}
The join() method turns the array into readable text. When the button is clicked, the function is run as Props.
4️⃣ Data Validation with PropTypes and defaultProps
Define PropTypes in AnimalCard.js:
import PropTypes from 'prop-types';
AnimalCard.propTypes = {
name: PropTypes.string.isRequired,
scientificName: PropTypes.string.isRequired,
size: PropTypes.number.isRequired,
diet: PropTypes.arrayOf(PropTypes.string).isRequired,
additional: PropTypes.shape({
link: PropTypes.string,
notes: PropTypes.string
}),
showAdditional: PropTypes.func.isRequired,
};
AnimalCard.defaultProps = {
additional: { notes: 'Ek bilgi bulunmamaktadır.' }
};
PropTypes checks at runtime and prints a warning on the console instead of an error. defaultProps provides safe fallback for missing data.
💡 Tip
If you accidentally type the size field as "200" (string), in the React console:
go
Warning: Failed prop type: Invalid prop size of type string supplied to AnimalCard, expected number. You will receive a warning.
❓ Frequently Asked Questions (FAQ)
- What is the difference between Props and State?
Props carry data from the parent component and cannot be changed. State is the data that changes within the component.
- Why are Props immutable?
React has a one-way data flow. Props do not change, only the parent component updates.
- Do PropTypes replace TypeScript?
No. PropTypes checks at run time, while TypeScript prevents the error at compile stage.
- Why is it useful to pass the function as Props?
It enables child components to manage events and send news to the parent component (callback structure).
- Why is Destructuring recommended?
Improves readability of code, props everywhere. It eliminates the need for writing.
🚀 Result
In this guide, you learned how to dynamicize your components using React Props, validate data types with PropTypes, and prevent the application from crashing in case of missing data with defaultProps. Now you can develop your components to be safer, flexible and reusable.
Try these methods now in the React projects you create on the GenixNode platform and see the difference! ⚡
yaml

