From 6f41686b15b7326079881d61da3009ad0b5136e0 Mon Sep 17 00:00:00 2001 From: Sina Bayati Date: Sat, 3 May 2025 05:20:48 +0330 Subject: [PATCH] fix: grammatical mistakes Fixed grammatical mistakes and updated the note section in "Why React Component Composition?" section --- blog/react-component-composition/index.md | 89 +++++++++++------------ 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/blog/react-component-composition/index.md b/blog/react-component-composition/index.md index c7eab42f..d9d6fa78 100644 --- a/blog/react-component-composition/index.md +++ b/blog/react-component-composition/index.md @@ -3,7 +3,13 @@ title: "React Component Composition" description: "React Component Composition step by step explained with examples. Learn the React Composition Pattern by example which helps you to render components within each other ..." date: "2019-01-30T13:50:46+02:00" categories: ["React"] -keywords: ["react component composition", "react component composition example", "react dynamic component composition", "react component composition pattern"] +keywords: + [ + "react component composition", + "react component composition example", + "react dynamic component composition", + "react component composition pattern", + ] hashtags: ["#ReactJs"] banner: "./images/banner.jpg" contribute: "" @@ -27,12 +33,13 @@ const convertCurrency = (amount, fromCurrency, toCurrency) => { }; ``` -In functional programming, the composition of functions is ubiquitous: +In functional programming, the composition of functions is commonplace: ```javascript -const convertCurrency = (amount, fromCurrency, toCurrency) => compose( +const convertCurrency = (amount, fromCurrency, toCurrency) => + compose( applyConversionRate(amount), - getConversionRate(fromCurrency, toCurrency), + getConversionRate(fromCurrency, toCurrency) ); ``` @@ -44,31 +51,29 @@ You have seen how multiple functions can be composed together to achieve somethi ```html
- +
``` -However, it's not only the form element but all of its other ingredients and their arrangement as well. It's the input field, the button, and the form that contribute to a greater goal: submit data. The example is taken a bit out of context, because the JavaScript function is missing, but not so the following React example. In React, a Form as React component which is rendered within a App component could look like the following: +However, it's not only the form element but all of its other ingredients and their arrangement as well. It's the input field, the button, and the form that contribute to a greater goal: submit data. The example is taken a bit out of context, because the JavaScript function is missing, but not so in the following React example. In React, a Form as React component which is rendered within an App component could look like the following: ```javascript -import React, { useState } from 'react'; +import React, { useState } from "react"; const App = () => { - const onSubmit = username => console.log(username); + const onSubmit = (username) => console.log(username); return
; }; const Form = ({ onSubmit }) => { - const [username, setUsername] = useState(''); + const [username, setUsername] = useState(""); return ( { + onSubmit={(event) => { onSubmit(username); // prevents browser from reloading @@ -82,7 +87,7 @@ const Form = ({ onSubmit }) => { setUsername(event.target.value)} + onChange={(event) => setUsername(event.target.value)} /> @@ -94,7 +99,7 @@ const Form = ({ onSubmit }) => { export default App; ``` -*Note: The Form component uses React Hooks that are not released yet. If you want, you can learn more about [React Hooks](/react-hooks/). Essentially they enable you to have function components with state and side-effects.* +_Note: The Form component uses React Hooks. Essentially they enable you to have function components with state and side-effects. You can check the [React docs page on Hooks](https://react.dev/reference/react/hooks) or if you want to, you can learn more about React Hooks in [this article](/react-hooks/)._ Now, wherever we use the Form component, we can capture the username of a user. It's identical to the HTML form from before, isn't it? Not really. At the moment, the Form is only capable of doing one thing. We did lose all the benefits from the HTML element composition from before, because we ended up with a specialized Form component. It can be reused anywhere in our React application, but it handles only one case. To make it effortless to see the difference, we would have to rename the Form component: @@ -141,7 +146,7 @@ Since we encapsulated everything in one React component, it's difficult to tear There is one property ([React prop](/react-pass-props-to-component/)) that helps us out with this dilemma for our React component: **the React children prop**. It's one special prop provided by React to render something within a component whereas the component isn't aware of it ahead of time. A basic example may be the following: ```javascript -const Button = ({ onClick, type = 'button', children }) => ( +const Button = ({ onClick, type = "button", children }) => ( @@ -343,7 +348,7 @@ const UsernameForm = ({ onSubmit }) => { ... ``` -From there it really depends on your React application on whether you want to use the generic Form component (e.g. Form) or specialize it as standalone Form component with a special use case (e.g. UsernameForm). My recommendation: Do the latter only if you catch yourself copying and pasting the same generic Form component from A to B to reuse it somewhere else. Then I would advice to implement this specialized Form component which encapsulates all the logic and can be reused anywhere in your application. In addition, it's beneficial for [testing your React component](/react-testing-tutorial/) in isolation. +From there it really depends on your React application on whether you want to use the generic Form component (e.g. Form) or specialize it as a standalone Form component with a special use case (e.g. UsernameForm). My recommendation: Do the latter only if you catch yourself copying and pasting the same generic Form component from A to B to reuse it somewhere else. Then I would advice to implement this specialized Form component which encapsulates all the logic and can be reused anywhere in your application. In addition, it's beneficial for [testing your React component](/react-testing-tutorial/) in isolation. # Fine-grained Props Control @@ -432,7 +437,7 @@ const Form = ({ buttonColor, onSubmit }) => { }; ``` -However, the Form component shouldn't care about any props for the button element. In order to generalize the shown non composed Form component even more, it would also have to take other props as arguments (e.g. "Your name"-label, "Send"-button label): +However, the Form component shouldn't care about any props for the button element. In order to generalize the shown non-composed Form component even more, it would also have to take other props as arguments (e.g. "Your name"-label, "Send"-button label): ```javascript{1,2,7,12,15,16,24} const Form = ({ label, buttonLabel, buttonColor, onSubmit }) => { @@ -465,19 +470,19 @@ const Form = ({ label, buttonLabel, buttonColor, onSubmit }) => { }; ``` -Suddenly you would end up with a cluttered component API for the Form component whereas the Form component takes care of everything rendered within itself. That can be avoided and that's why component compositions are such powerful pattern in React. Every component takes care about itself yet contributes to a greater goal in the component hierarchy of a React application. +Suddenly you would end up with a cluttered component API for the Form component whereas the Form component takes care of everything rendered within itself. That can be avoided and that's why component compositions are such powerful patterns in React. Every component takes care about itself yet contributes to a greater goal in the component hierarchy of a React application. ```javascript -import React, { useState } from 'react'; +import React, { useState } from "react"; const App = () => { - const onSubmit = username => console.log(username); + const onSubmit = (username) => console.log(username); - const [username, setUsername] = useState(''); + const [username, setUsername] = useState(""); return ( { + onSubmit={(event) => { onSubmit(username); event.preventDefault(); }} @@ -497,17 +502,8 @@ const Form = ({ onSubmit, children }) => ( {children}
); -const Button = ({ - color = 'white', - onClick, - type = 'button', - children, -}) => ( - ); @@ -518,7 +514,7 @@ const InputField = ({ value, onChange, children }) => ( onChange(event.target.value)} + onChange={(event) => onChange(event.target.value)} /> ); @@ -574,16 +570,13 @@ This pattern, not widely known under the synonym [slot pattern](/react-pass-prop Often you see something like the following App component whereas React Router is used to compose dynamic components, depending on the selected route (URL), into the Route components: ```javascript -import React from 'react'; -import { - BrowserRouter as Router, - Route, -} from 'react-router-dom'; +import React from "react"; +import { BrowserRouter as Router, Route } from "react-router-dom"; -import Navigation from './Navigation'; -import LandingPage from './Landing'; -import SignUpPage from './SignUp'; -import SignInPage from './SignIn'; +import Navigation from "./Navigation"; +import LandingPage from "./Landing"; +import SignUpPage from "./SignUp"; +import SignInPage from "./SignIn"; const App = () => ( @@ -592,9 +585,9 @@ const App = () => (
- - - + + +