DEV Community

Hee
Hee

Posted on • Edited on

[React] Props

Props

  • Values(properties) passed from a parent component
  • They receive props as arguments, similar to function arguments, and return React elements that describe how the UI should be rendered based on those props
  • You can pass dynamic data (state) as well as static data
  • Props are read-only objects

Pitfall

  • Modifying props within a child component affects the value of the props passed by the parent component

-> This violates the unidirectional, downward data flow principle of React

-> It can lead to unintended side effects.

Side effects

: it refers to any modification or action that occurs outside the scope of the component rendering

  • it happens as a result of a component's execution, but not as a direct consequence of updating its state or props

[e.g.]

  • Modifying the DOM directly using imperative APIs.
  • Making AJAX requests or fetching data from an API.
  • Subscribing to events or adding event listeners.
  • Modifying shared state outside of the component, such as a global store.
  • Timer or interval functions.

How to use props

  • Regardless of the number of props, they are always delivered in objects
  • After being passed from the parent component, it can be received through a parameter and then used
  • To use the props, use the dot notation method to read the value (props is an object)

[Parent Component]
1) Define the values and attributes you want to pass to the child component

2) Pass the defined values and attributes using props

  • 1 - Pass props to a React component similar to passing arguments to a function
  • 2 - Place the value within the opening and closing tags to pass it

[Child Component]
3) Render the received props

  • 1 - Access the value by using dot notation on the props object
  • 2 - Access the value using props.children

[e.g.1] Pass props to a React component

function Parent() {
  return (
    <div className="parent">
      <h1>I'm the parent</h1>
      // here
      <Child text={"I'm the eldest child"} />
    </div>
  );
};

function Child(props) {
  return (
    <div className="child">
      //here    
      <p>{props.text}</p>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

[e.g.2] Place the value within the opening and closing tags

function Parent() {
  return (
    <div className="parent">
        <h1>I'm the parent</h1>
        // here
        <Child>I'm the eldest child</Child>
    </div>
  );
};

function Child(props) {
  return (
    <div className="child">
        // here
        <p>{props.children}</p>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Various types of props

1. Primitive types:

Such as strings, numbers, booleans, and null.

<ChildComponent name="John" age={25} isStudent={true} />
Enter fullscreen mode Exit fullscreen mode

2. Objects:

It's important to note that objects are passed by reference, so if the object changes in the parent component, it will affect the child component.

const person = { name: "John", age: 25 };
<ChildComponent person={person} />
Enter fullscreen mode Exit fullscreen mode

3. Arrays:

const numbers = [1, 2, 3, 4, 5];
<ChildComponent numbers={numbers} />
Enter fullscreen mode Exit fullscreen mode

4. Functions:

It is useful for passing callback functions from the parent component to the child component.

const handleClick = () => {
  console.log('Button clicked!');
};
<ChildComponent onClick={handleClick} />
Enter fullscreen mode Exit fullscreen mode

5. React elements:

const title = <h1>Hello, world!</h1>;
<ChildComponent title={title} />
Enter fullscreen mode Exit fullscreen mode

6. Components

[Container.js]

  • Style components passed as props using inline styles
const Container=({children})=>{
//console.log(children);
//Symbol(react.element)
return (
    <div style={{margin:20, padding:20, border:"1px solid gray"}}>
    {children}
    </div>
    );
};
export default Container;
Enter fullscreen mode Exit fullscreen mode

[App.js]

import Container from "./Container";
...

function App(
...
    return(
        <Container>
            <div>
                <MyHeader/>
                <Counter {...counterProps}/>
            </div>
        </Container>
)
Enter fullscreen mode Exit fullscreen mode
  • The jsx elements placed between the components are passed to the Container component as a prop called children.

Practice

1. Render the passed props!

  • Write code to render two strings by passing itemOne & itemTwo in the App component as props to the Learn component
const App = () => {
  const itemOne = "I'm learning";
  const itemTwo = "React!";

  return (
    <div className="App">

    // pass the props
      <Learn text={itemOne} />
      <Learn> {itemTwo} </Learn>
    </div>
  );
};

const Learn = (props) => {
  //Rendering using passed props
  return (
    <div className="Learn">
      {props.text}
      {props.children}
    </div>
  );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

2. Pass the prop!

[App.js]

import React from "react"
import Counter from "./Counter"

function App(){
    return (
        <div>
        <Counter initialValue={5}/> 
        </div>
    )
Enter fullscreen mode Exit fullscreen mode

[Counter.js]

import React, {useState} from "react"

const Counter=(props)=>{
//make sure you got it right
//console.log("props")

const [count, setCount]=useState(props.initialValue);

const onIncrease=()=>{
    setCount(count+1);
};

const onDecrease=()=>{
    setCount(count-1);
};

return (
    <div>
        <h2>{count}</h2>
        <button onClick={onIncrease}>+</button>
        <button onClick={onDecrease}>-</button>
    </div>
    )
};

export default Counter;
Enter fullscreen mode Exit fullscreen mode

3. Pass the props!

  • If there are many props that need to be passed, we can use spread operator to pass all the props.
  • this allows us to pass an object containing multiple props without explicitly specifying each prop individually

[App.js]

function App(){
    const counterProps={
    a:1,
    b:2,
    c:3,
    d:4,
    e:5,
    initialValue:5 ,
    };

    return (
        <div>
        <Counter {...counterProps}/>
        </div>
    )
Enter fullscreen mode Exit fullscreen mode

[Counter.js]

import React, {useState} from "react"
import OddEvenResult from "./OddEvenReslt"

const Counter=({initialValue})=>{

const [count, setCount]=useState({initialValue});

const onIncrease=()=>{
    setCount(count+1);
};

const onDecrease=()=>{
    setCount(count-1);
};

return (
    <div>
        <h2>{count}</h2>
        <button onClick={onIncrease}>+</button>
        <button onClick={onDecrease}>-</button>
        <OddEvenResult count={count}
    </div>
    )
};

export default Counter;
Enter fullscreen mode Exit fullscreen mode
  • Receive and use only necessary values ​from objects through destructing assignment
  • The state of the count is being passed to the OddEvenResult component
  • If props (initialValue) is not passed down from the parent component, but child component receives the props, 'undefined' is printed to the console. →const[count,setCount]=useState({initialValue}); Undefined is used as state value by code → NaN (error)

[Solution]
Counter.defaultProps={
initialValue:0
}

  • Error prevention by setting the default value of props that were not delivered through defaultProps value setting

[OddEvenResult.js]

  • A component that determines whether count is odd or even
const OddEvenResult=({count})=>{
    return<>{count%2===0?"짝수":"홀수"}</>
}  

export default OddEvenResult;
Enter fullscreen mode Exit fullscreen mode
  • re-rendering React components re-render when their parent props change. OddEvenResult renders a different result each time the Counter's state changes.
  • Even if props are not passed from the parent element, when the parent element's state changes, the child element's component is also re-rendered.

Re-redering

  • When the state value managed by the component changes
  • When the props that come down to the child component change
  • Even if neither of the above two cases, when its parent is re-rendered

Top comments (0)