Components vs Widgets
Everything in Flutter is a widget, similar to how everything in React is a component. Both use a declarative UI paradigm.
React
// React functional component
function Greeting({ name }) {
  return (
    <div className="greeting">
      <h1>Hello, {name}!</h1>
      <p>Welcome to React</p>
    </div>
  );
}
// Usage
<Greeting name="Alice" />
    Flutter
// Flutter widget
class Greeting extends StatelessWidget {
  final String name;
  
  const Greeting({required this.name});
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Hello, $name!'),
        Text('Welcome to Flutter'),
      ],
    );
  }
}
// Usage
Greeting(name: 'Alice')
    Key differences
- React uses JSX, Flutter uses Dart with nested widget constructors.
 - React components return JSX, Flutter widgets return widgets from 
build(). - Props are passed as constructor parameters in Flutter.
 - Flutter uses 
StatelessWidgetfor static components. 
State Management
Flutter's StatefulWidget is similar to React's class components or useState hook.
React
// React with useState hook
function Counter() {
  const [count, setCount] = useState(0);
  
  const increment = () => {
    setCount(count + 1);
  };
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>
        Increment
      </button>
    </div>
  );
}
    Flutter
// Flutter StatefulWidget
class Counter extends StatefulWidget {
  @override
  State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
  int count = 0;
  
  void increment() {
    setState(() {
      count++;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $count'),
        ElevatedButton(
          onPressed: increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}
    Key differences
- Flutter uses 
setState()to trigger rebuilds, similar tosetCount(). StatefulWidgetrequires a separate State class.- State persists in the State object, not via hooks.
 - Flutter doesn't have a virtual DOM; it rebuilds widget trees efficiently.
 
Lifecycle Methods
Flutter's lifecycle methods map closely to React hooks and class component lifecycle.
React
// React useEffect hook
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    // Component mounted
    fetchUser(userId).then(setUser);
    
    return () => {
      // Component will unmount
      cleanup();
    };
  }, [userId]); // Dependencies
  
  return <div>{user?.name}</div>;
}
        Flutter
// Flutter lifecycle
class UserProfile extends StatefulWidget {
  final String userId;
  const UserProfile({required this.userId});
  
  @override
  State<UserProfile> createState() => 
    _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
  User? user;
  
  @override
  void initState() {
    super.initState();
    // Component mounted
    fetchUser(widget.userId).then((u) {
      setState(() => user = u);
    });
  }
  
  @override
  void dispose() {
    // Component will unmount
    cleanup();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Text(user?.name ?? '');
  }
}
        Key differences
initState()is likeuseEffectwith empty dependencies.dispose()is the cleanup function inuseEffect.didUpdateWidget()is likeuseEffectwith dependencies.- Access props via 
widget.propNamein the State class. 
Styling & Layout
Flutter uses widget-based styling instead of CSS. Flexbox concepts translate to Row, Column, and Flex.
React
// React with CSS/styled-components
function Card({ title, children }) {
  return (
    <div style={{
      backgroundColor: '#fff',
      borderRadius: '8px',
      padding: '16px',
      boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
      display: 'flex',
      flexDirection: 'column',
      gap: '8px'
    }}>
      <h2 style={{ 
        fontSize: '20px',
        fontWeight: 'bold'
      }}>
        {title}
      </h2>
      {children}
    </div>
  );
}
        Flutter
// Flutter with widget styling
class CardWidget extends StatelessWidget {
  final String title;
  final List<Widget> children;
  
  const CardWidget({
    required this.title,
    required this.children,
  });
  
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(8),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.1),
            blurRadius: 4,
            offset: Offset(0, 2),
          ),
        ],
      ),
      padding: EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            title,
            style: TextStyle(
              fontSize: 20,
              fontWeight: FontWeight.bold,
            ),
          ),
          SizedBox(height: 8),
          ...children,
        ],
      ),
    );
  }
}
        Key differences
- Flutter uses 
Containerfor styling (like a styled div). Row= flexDirection row,Column= flexDirection column.EdgeInsetsfor padding/margin instead of CSS values.SizedBoxfor spacing instead of gap or margin.- No CSS selectors; all styling is done programmatically.
 
Lists & Iteration
Both frameworks efficiently render lists of items with keys for optimization.
React
// React list rendering
function TodoList({ todos }) {
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>
          {todo.title}
        </li>
      ))}
    </ul>
  );
}
// Optimized list (virtualization)
import { FixedSizeList } from 
  'react-window';
function VirtualList({ items }) {
  return (
    <FixedSizeList
      height={400}
      itemCount={items.length}
      itemSize={50}
    >
      {({ index, style }) => (
        <div style={style}>
          {items[index].title}
        </div>
      )}
    </FixedSizeList>
  );
}
        Flutter
// Flutter list rendering
class TodoList extends StatelessWidget {
  final List<Todo> todos;
  
  const TodoList({required this.todos});
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: todos.map((todo) => 
        Text(todo.title, key: Key(todo.id))
      ).toList(),
    );
  }
}
// Optimized list (built-in virtualization)
class VirtualList extends StatelessWidget {
  final List<Item> items;
  
  const VirtualList({required this.items});
  
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(items[index].title),
        );
      },
    );
  }
}
        Key differences
- Flutter's 
ListView.builderis lazy by default (like react-window). - Use 
.map().toList()for simple lists in Flutter. - Keys work similarly for widget identity and optimization.
 ListView.separatedadds dividers automatically.
Navigation & Routing
Flutter's Navigator is similar to React Router, with push/pop semantics for screen navigation.
React
// React Router
import { 
  BrowserRouter,
  Routes,
  Route,
  useNavigate
} from 'react-router-dom';
function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/profile/:id" 
          element={<Profile />} />
      </Routes>
    </BrowserRouter>
  );
}
// Navigation
function Home() {
  const navigate = useNavigate();
  
  const goToProfile = () => {
    navigate('/profile/123');
  };
  
  return (
    <button onClick={goToProfile}>
      View Profile
    </button>
  );
}
        Flutter
// Flutter Navigator
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/': (context) => HomeScreen(),
        '/profile': (context) => ProfileScreen(),
      },
    );
  }
}
// Navigation
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        Navigator.pushNamed(
          context,
          '/profile',
          arguments: {'id': '123'},
        );
      },
      child: Text('View Profile'),
    );
  }
}
// Receiving parameters
class ProfileScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!
      .settings.arguments as Map;
    return Text('User ID: ${args['id']}');
  }
}
        Key differences
Navigator.pushis like React Router'snavigate().Navigator.popgoes back (likenavigate(-1)).- Use 
go_routerpackage for advanced routing (similar to React Router). - Flutter uses route names instead of path strings.
 
Forms & Input Handling
Both frameworks use controlled components pattern for form inputs.
React
// React controlled input
function LoginForm() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = 
    useState('');
  
  const handleSubmit = (e) => {
    e.preventDefault();
    login(email, password);
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => 
          setEmail(e.target.value)
        }
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => 
          setPassword(e.target.value)
        }
        placeholder="Password"
      />
      <button type="submit">
        Login
      </button>
    </form>
  );
}
        Flutter
// Flutter form with controllers
class LoginForm extends StatefulWidget {
  @override
  State<LoginForm> createState() => 
    _LoginFormState();
}
class _LoginFormState extends State<LoginForm> {
  final _emailController = 
    TextEditingController();
  final _passwordController = 
    TextEditingController();
  
  void _handleSubmit() {
    login(
      _emailController.text,
      _passwordController.text,
    );
  }
  
  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: _emailController,
          decoration: InputDecoration(
            hintText: 'Email',
          ),
        ),
        TextField(
          controller: _passwordController,
          obscureText: true,
          decoration: InputDecoration(
            hintText: 'Password',
          ),
        ),
        ElevatedButton(
          onPressed: _handleSubmit,
          child: Text('Login'),
        ),
      ],
    );
  }
}
        Key differences
- Flutter uses 
TextEditingControllerinstead of state for inputs. - Controllers must be disposed in 
dispose()method. - Use 
Formwidget withTextFormFieldfor validation. - No synthetic events; access text via 
controller.text. 
HTTP Requests & Data Fetching
Both use async/await for API calls. Flutter's http package is similar to fetch or axios.
React
// React with fetch
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = 
    useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      })
      .catch(err => {
        setError(err);
        setLoading(false);
      });
  }, [userId]);
  
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error!</div>;
  
  return <div>{user.name}</div>;
}
        Flutter
// Flutter with http package
import 'package:http/http.dart' as http;
class UserProfile extends StatefulWidget {
  final String userId;
  const UserProfile({required this.userId});
  
  @override
  State<UserProfile> createState() => 
    _UserProfileState();
}
class _UserProfileState extends State<UserProfile> {
  User? user;
  bool loading = true;
  String? error;
  
  @override
  void initState() {
    super.initState();
    fetchUser();
  }
  
  Future<void> fetchUser() async {
    try {
      final response = await http.get(
        Uri.parse('/api/users/${widget.userId}')
      );
      final data = jsonDecode(response.body);
      setState(() {
        user = User.fromJson(data);
        loading = false;
      });
    } catch (e) {
      setState(() {
        error = e.toString();
        loading = false;
      });
    }
  }
  
  @override
  Widget build(BuildContext context) {
    if (loading) return CircularProgressIndicator();
    if (error != null) return Text('Error!');
    
    return Text(user!.name);
  }
}
        Key differences
- Add 
httppackage topubspec.yamldependencies. - Use 
Uri.parse()for URLs in Flutter. jsonDecode()is likeJSON.parse().- Consider 
diopackage for advanced features (like axios). 
Global State Management
Flutter has several state management solutions. Provider is similar to React Context, while Riverpod is like Redux/Zustand.
React
// React Context API
const ThemeContext = createContext();
function App() {
  const [theme, setTheme] = useState('light');
  
  return (
    <ThemeContext.Provider 
      value={{ theme, setTheme }}
    >
      <MainContent />
    </ThemeContext.Provider>
  );
}
// Consuming context
function ThemeToggle() {
  const { theme, setTheme } = 
    useContext(ThemeContext);
  
  return (
    <button onClick={() => 
      setTheme(theme === 'light' 
        ? 'dark' : 'light')
    }>
      Toggle Theme
    </button>
  );
}
        Flutter
// Flutter Provider
class ThemeProvider extends ChangeNotifier {
  String _theme = 'light';
  
  String get theme => _theme;
  
  void setTheme(String newTheme) {
    _theme = newTheme;
    notifyListeners();
  }
}
// Setup provider
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => ThemeProvider(),
      child: MyApp(),
    ),
  );
}
// Consuming provider
class ThemeToggle extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final themeProvider = 
      Provider.of<ThemeProvider>(context);
    
    return ElevatedButton(
      onPressed: () {
        themeProvider.setTheme(
          themeProvider.theme == 'light' 
            ? 'dark' : 'light'
        );
      },
      child: Text('Toggle Theme'),
    );
  }
}
        Key differences
- Provider uses 
ChangeNotifierinstead of hooks. notifyListeners()triggers rebuilds (likesetState).- Alternatives: Riverpod (hooks-like), Bloc (Redux-like), GetX.
 - Use 
Consumerwidget for granular rebuilds. 
Animations
Both frameworks have rich animation APIs. Flutter's animations are similar to React Spring or Framer Motion.
React
// React with CSS transitions
function FadeIn({ children }) {
  const [visible, setVisible] = 
    useState(false);
  
  useEffect(() => {
    setVisible(true);
  }, []);
  
  return (
    <div style={{
      opacity: visible ? 1 : 0,
      transition: 'opacity 0.5s ease-in'
    }}>
      {children}
    </div>
  );
}
// With Framer Motion
import { motion } from 'framer-motion';
function AnimatedBox() {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5 }}
    >
      Content
    </motion.div>
  );
}
        Flutter
// Flutter implicit animations
class FadeIn extends StatefulWidget {
  final Widget child;
  const FadeIn({required this.child});
  
  @override
  State<FadeIn> createState() => 
    _FadeInState();
}
class _FadeInState extends State<FadeIn> {
  bool visible = false;
  
  @override
  void initState() {
    super.initState();
    Future.microtask(() => 
      setState(() => visible = true)
    );
  }
  
  @override
  Widget build(BuildContext context) {
    return AnimatedOpacity(
      opacity: visible ? 1.0 : 0.0,
      duration: Duration(milliseconds: 500),
      curve: Curves.easeIn,
      child: widget.child,
    );
  }
}
// Simpler implicit animation
AnimatedContainer(
  duration: Duration(milliseconds: 500),
  opacity: visible ? 1.0 : 0.0,
  transform: Matrix4.translationValues(
    0, visible ? 0 : 20, 0
  ),
  child: Text('Content'),
)
        Key differences
- Flutter has built-in animation widgets (no extra packages needed).
 AnimatedContainer,AnimatedOpacityfor implicit animations.AnimationControllerfor explicit control (like CSS keyframes).Herowidget for shared element transitions.
Ready to learn more? Visit the Flutter Documentation or Dart Language Tour.