Component Communication
React components are self-contained units that manage their own state by default. In component-based development, we break complex functionality into smaller components to build complete applications efficiently.
Props Mechanism
Props enable components to receive external data. Components accept data through attributes in their JSX tags.
- Function components receive props via function parameters
- Class components access props through this.props
Function Component Communication
Function Component Example
import React from 'react';
import ReactDOM from 'react-dom';
function DisplayItem({ vehicle, amount }) {
return (
<div>
<h2>Display Component</h2>
<p>Vehicle: {vehicle}</p>
<p>Amount: {amount}</p>
</div>
);
}
class MainApp extends React.Component {
render() {
return (
<div>
<h1>Main Application</h1>
<DisplayItem vehicle="blue sports car" amount={200} />
</div>
);
}
}
ReactDOM.render(<MainApp />, document.getElementById('root'));
Props Characteristics
- Accept any data type
- Read-only nature (one-way data flow)
- Class constructors require props passed to super()
class Welcome extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div>Received value: {this.props.count}</div>;
}
}
Component Communication Patterns
Parent to Child Communication
Parent provides state data and passes it to child components via props.
class Container extends React.Component {
state = { userName: '' };
handleInput = (e) => {
this.setState({ userName: e.target.value });
};
render() {
return (
<div>
<input type="text" onChange={this.handleInput} />
<ChildComponent name={this.state.userName} />
</div>
);
}
}
function ChildComponent({ name }) {
return <div>Hello {name}</div>;
}
Child to Parent Communication
Parent provides callback functions that children invoke to pass data upward.
class ParentComponent extends React.Component {
state = { receivedData: '' };
handleDataFromChild = (data) => {
this.setState({ receivedData: data });
};
render() {
return (
<div>
<ChildComponent sendData={this.handleDataFromChild} />
<p>From child: {this.state.receivedData}</p>
</div>
);
}
}
class ChildComponent extends React.Component {
state = { inputValue: '' };
handleChange = (e) => {
this.setState({ inputValue: e.target.value });
this.props.sendData(e.target.value);
};
render() {
return <input type="text" onChange={this.handleChange} />;
}
}
Context API Communication
For sharing data across multiple components without prop drilling.
const DataContext = React.createContext();
class App extends React.Component {
state = { theme: 'dark' };
render() {
return (
<DataContext.Provider value={this.state.theme}>
<Header />
<Content />
</DataContext.Provider>
);
}
}
function Content() {
return (
<DataContext.Consumer>
{theme => <div style={{ color: theme === 'dark' ? 'white' : 'black' }}>
Current theme: {theme}
</div>}
</DataContext.Consumer>
);
}
Children Prop Pattern
Passing components and elements as children to other components.
function Card({ title, children }) {
return (
<div className="card">
<h3>{title}</h3>
{children}
</div>
);
}
// Usage
<Card title="User Profile">
<img src="avatar.jpg" alt="Avatar" />
<p>User description here</p>
</Card>
Props Validation
Ensure components receive correct data types using PropTypes.
import PropTypes from 'prop-types';
function UserCard({ name, age, email }) {
return (
<div>
<h3>{name}</h3>
<p>Age: {age}</p>
<p>Email: {email}</p>
</div>
);
}
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
email: PropTypes.string
};
UserCard.defaultProps = {
age: 18,
email: 'no-email@provided.com'
};