SoFunction
Updated on 2025-04-07

Props features and applications in React

Preface

Component reuse is a common requirement in React development. Sometimes, we need to share the state or behavior of a certain component with other components. Traditionally, it is implemented through Higher-Order Components (HOCs), but this approach sometimes brings some complexity and readability issues. Render Props provides a cleaner and more flexible way to share the state and behavior of components. This article will introduce in detail the concept, implementation methods and application scenarios of Render Props.

1.1Props details

propsIt is normal and is passed in externally. The settings inside the component can also be initialized in some ways. The properties cannot be changed by the component itself, but you can pass in new ones through the parent component's active re-rendering method.props

React is very flexible, but it also has a strict rule:

All React components must protect their props from being changed like pure functions.

Pure function: input is certain, output is certain

In general, when using a component, you can put parameters in the attributes of the tag, and all attributes will be used as components.propsThe key value of the object.

Components created by arrow functions need to be received through the function's parametersprops

Components created through classes need to be passedCome and receive

Components can refer to other components in their output.

This allows us to use the same component to abstract details at any level.

Buttons, forms, dialogs, and even the content of the entire screen: In React applications, these are usually represented as components.

1.2 Parent-child component communication

1.2.1 Building a parent-child component

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpackimport App from './01-App-parent-child'
​
const root = (('root'))
​
(<App />)

src/

import React from 'react'
// ?  Why must the first letter of a component in react be capitalized?// If lowercase, it is considered as a tag inherent to html, and if html tag does not appear​
const Header = () => {
  return (
    <header>react The core library focuses only on view layers</header>
  )
}
​
class Content extends  {
  render () {
    return (
      <div>react 16.8 Launched react hooks</div>
    )
  }
}
​
const Footer = () => {
  return (
    <footer>reactIt's really simple</footer>
  )
}
​
class App extends  {
  render () {
    return (
      <div>
        <Header></Header>
        <Content></Content>
        <Footer></Footer>
      </div>
    )
  }
}
​
export default App

1.2.2 Parent component passes values ​​to child component

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
import App from './02-App-parent-child-value'
​
const root = (('root'))
​
(<App />)

src/

import React from 'react'
// The parent component adds a custom attribute where the child component is called. If the value of the attribute is a variable or boolean type,// Number type, object, array, null, undefined, function, need to use {} package​
​
// If the child component is a class component, inside the child component, the data passed by the parent component can be accessed through// If the child component is a functional component, the function has the default parameter to props, and the data passed by the parent component can be accessed through props​
const Header = (props) => {
  (props) // { name: '' }
  return (
    <header>{  } The core library focuses only on view layers</header>
  )
}
​
class Content extends  {
  render () {
    () // {version: 16.8}
    return (
      <div>react {  } Launched react hooks</div>
    )
  }
}
​
const Footer = ({ msg }) => { // Deconstructed msg from props object  return (
    <footer>reactReally very{ msg }</footer>
  )
}
​
class App extends  {
  render () {
    return (
      <div>
        <Header name=""></Header>
        <Content version={ 16.8 }></Content>
        <Footer msg="Simple"></Footer>
      </div>
    )
  }
}
​
export default App

1.2.3 The parent component sets the default value to the child component

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
import App from './03-App-parent-child-value-default'
​
const root = (('root'))
​
(<App />)

src/

import React from 'react'
// The parent component adds a custom attribute where the child component is called. If the value of the attribute is a variable or boolean type,// Number type, object, array, null, undefined, function, need to use {} package​
// If the child component is a class component, inside the child component, the data passed by the parent component can be accessed through// If the child component is a functional component, the function has the default parameter to props, and the data passed by the parent component can be accessed through props​
// If you need to set default values ​​for child components// Whether it is a class component or a functional component, after defining the component, add the defaultProps property// If it is a class component, you can also set the default value through the static properties of the class​
const Header = (props) => {
  (props) // { name: '' }
  return (
    <header>{  } The core library focuses only on view layers</header>
  )
}
 = {
  name: ''
}
​
class Content extends  {
  static defaultProps = { // Static properties of the class    version: 16.8
  }
  render () {
    () // {version: 16.8}
    return (
      <div>react {  } Launched react hooks!</div>
    )
  }
}
//  = {
//   version: 16.8
// }
​
const Footer = ({ msg }) => { // Deconstructed msg from props object  return (
    <footer>reactReally very{ msg }</footer>
  )
}
 = {
  msg: 'Simple'
}
class App extends  {
  render () {
    return (
      <div>
        {/* <Header name=""></Header>
         <Content version={ 16.8 }></Content>
         <Footer msg="Simple"></Footer> */}
        &lt;Header&gt;&lt;/Header&gt;
        &lt;Content&gt;&lt;/Content&gt;
        &lt;Footer&gt;&lt;/Footer&gt;
      &lt;/div&gt;
    )
  }
}
​
export default App

1.2.4 Verification using prop-types attribute

Since React v15.5,Moved into another package. Please useprop-types libraryreplace.

$ cnpm i prop-types -D
import PropTypes from 'prop-types';
​
 = {
// You can declare attributes as JS native type, by default// These properties are optional.optionalArray: ,
optionalBool: ,
optionalFunc: ,
optionalNumber: ,
optionalObject: ,
optionalString: ,
optionalSymbol: ,
​
// Any element that can be rendered (including numbers, strings, elements or arrays)// (or Fragment) also contains these types.optionalNode: ,
​
// A React element.optionalElement: ,
​
// A React element type (i.e., MyComponent).optionalElementType: ,
​
// You can also declare prop as an instance of the class, use it here// JS instanceof operator.optionalMessage: (Message),
​
// You can make your prop only a specific value, specify it as// Enumeration type.optionalEnum: (['News', 'Photos']),
​
// An object can be any of several typesoptionalUnion: ([
,
,
(Message)
]),
​
// You can specify that an array is composed of elements of a certain typeoptionalArrayOf: (),
​
// You can specify that an object consists of a value of a certain typeoptionalObjectOf: (),
​
// You can specify that an object consists of a specific type valueoptionalObjectWithShape: ({
color: ,
fontSize: 
}),
​
// An object with warnings on extra properties
optionalObjectWithStrictShape: ({
name: ,
quantity: 
}),
​
// You can add `isRequired` to any PropTypes property to ensure// When this prop is not provided, a warning message will be printed.requiredFunc: ,
​
// Required data of any typerequiredAny: ,
​
// You can specify a custom validator.  It should return an Error object when validation fails.// Please do not use `` or throw exceptions, as this will not work in `oneOfType`.customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
  'Invalid prop `' + propName + '` supplied to' +
  ' `' + componentName + '`. Validation failed.'
);
}
},
​
// You can also provide a custom `arrayOf` or `objectOf` validator.// It should return an Error object when validation fails.// The validator will verify each value in the array or object.  The first two parameters of the validator// The first one is the array or object itself// The second one is their current key.customArrayProp: (function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
  'Invalid prop `' + propFullName + '` supplied to' +
  ' `' + componentName + '`. Validation failed.'
);
}
})
};

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
// import App from './03-App-parent-child-value-default'
import App from './04-App-parent-child-value-default-type'
​
const root = (('root'))
​
(&lt;App /&gt;)

src/

import React from 'react'
import PropTypes from 'prop-types'
// The parent component adds a custom attribute where the child component is called. If the value of the attribute is a variable or boolean type,// Number type, object, array, null, undefined, function, need to use {} package​
// If the child component is a class component, inside the child component, the data passed by the parent component can be accessed through// If the child component is a functional component, the function has the default parameter to props, and the data passed by the parent component can be accessed through props​
// If you need to set default values ​​for child components// Whether it is a class component or a functional component, after defining the component, add the defaultProps property// If it is a class component, you can also set the default value through the static properties of the class​
// If you need to verify the data type of the data passed by the parent component// It needs to be completed through the third-party module prop-types// Whether it is a class component or a functional component, the type verification is completed after defining the component.// Completed through component.propTypes, written as an object// The key value is the custom attribute name set when the parent component calls the child component// The value is PropTypes.Data type​
// If the custom property value must be passed, it will be done through PropTypes.data type.isRequired// If the custom attribute value can be of type number or type stirng,// Set by ([ , ])​
const Header = (props) =&gt; {
  (props) // { name: '' }
  return (
    &lt;header&gt;{  } The core library focuses only on view layers&lt;/header&gt;
  )
}
 = {
  name: ''
}
 = { // The first letter is not capitalized  // name:  
  name:  
}
​
class Content extends  {
  static defaultProps = { // Static properties of the class    version: 16.8
  }
  render () {
    () // {version: 16.8}
    return (
      &lt;div&gt;react {  } Launched react hooks!&lt;/div&gt;
    )
  }
}
//  = {
//   version: 16.8
// }
​
 = {
  // version: 
  version: ([
    , 
  ])
}
​
const Footer = ({ msg }) =&gt; { // Deconstructed msg from props object  return (
    &lt;footer&gt;reactReally very{ msg }&lt;/footer&gt;
  )
}
 = {
  msg: 'Simple'
}
 = {
  // msg:  // Invalid prop `msg` of type `string` supplied to `Footer`, expected `boolean`
  msg: 
}
class App extends  {
  render () {
    return (
      &lt;div&gt;
        {/* <Header name=""></Header>
         <Content version={ 16.8 }></Content>
         <Footer msg="Simple"></Footer> */}
        &lt;Header&gt;&lt;/Header&gt;
        &lt;Content&gt;&lt;/Content&gt;
        &lt;Footer&gt;&lt;/Footer&gt;
      &lt;/div&gt;
    )
  }
}
​
export default App

1.3

We know that when using components, they can be nested. To use nested structures in custom components, you need to use

Equivalent to slot in vue

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
// import App from './03-App-parent-child-value-default'
// import App from './04-App-parent-child-value-default-type'
import App from './05-App-props-children'
​
const root = (('root'))
​
(&lt;App /&gt;)
​

src/

import React from 'react'
​
const Header = (props) =&gt; {
  return (
    &lt;header&gt;1 {  }&lt;/header&gt;
  )
}
​
class Content extends  {
  render () {
    return (
      &lt;div&gt;2 {  }&lt;/div&gt;
    )
  }
}
​
const Footer = ({ children }) =&gt; {
  return (
    &lt;footer&gt;3 { children }&lt;/footer&gt;
  )
}
​
class App extends  {
  render () {
    return (
      &lt;div&gt;
        &lt;Header&gt;react The core library focuses only on view layers&lt;/Header&gt;
        &lt;Content&gt;react 16.8 Launched react hooks&lt;/Content&gt;
        &lt;Footer&gt;reactIt's really simple&lt;/Footer&gt;
      &lt;/div&gt;
    )
  }
}
​
export default App

If you need to add multiple elements to the component and display them in multiple locations, you can set it as follows:

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
// import App from './03-App-parent-child-value-default'
// import App from './04-App-parent-child-value-default-type'
// import App from './05-App-props-children'
import App from './06-App-mutiple-props-children'
​
const root = (('root'))
​
(&lt;App /&gt;)

src/

import React from 'react'
​
// Use named slots in vue (<slot name=""></slot>)// react needs to rely on the subscript ofconst Header = (props) =&gt; {
  (props)
  return (
    &lt;header&gt;
      &lt;div&gt;Output here1Value of { [0] }&lt;/div&gt;
      &lt;div&gt;Output here2Value of { [1] }&lt;/div&gt;
      &lt;div&gt;Output here3Value of { [2] }&lt;/div&gt;
    &lt;/header&gt;
  )
}
​
class App extends  {
  render () {
    return (
      &lt;div&gt;
        &lt;Header&gt;
          &lt;div&gt;1111111&lt;/div&gt;
          &lt;div&gt;2222222&lt;/div&gt;
          &lt;div&gt;3333333&lt;/div&gt;
        &lt;/Header&gt;
      &lt;/div&gt;
    )
  }
}
​
export default App

Implementing a named slot similar to vue, you need to access it through the subscript of

1.4 render props feature

Use Render Props to solve Cross-Cutting Concerns

Components are the main unit of React code reuse, but it is not always obvious how to share the state or behavior of one component encapsulated to other components that require the same state.

The following components track mouse locations in a web application:

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
// import App from './03-App-parent-child-value-default'
// import App from './04-App-parent-child-value-default-type'
// import App from './05-App-props-children'
// import App from './06-App-mutiple-props-children'
import App from './07-App-mouse-tracker'
​
const root = (('root'))
​
(&lt;App /&gt;)
​

src/

There is no learning state state and event processing yet, so use it first

import { Component } from 'react'
​
// The react event needs to be used onMouseMove// Native js onmounsemove// react event meets two conditions: the first must be an event, and the second this points to the current componentclass App extends Component {
  // The initialization state of react class component, similar to data in vue  state = { 
    x: 0,
    y: 0
  }
​
  render() { 
    return (
      &lt;div style={ { width: '100vw', height: '100vh', backgroundColor: '#f66'} } onMouseMove = { (event) =&gt; {
        (event)
        // Modify the initialization value        ({
          x: ,
          y: 
        })
      } }&gt;
        &lt;p&gt;
          The current mouse position is,x:{  },y: {  }
        &lt;/p&gt;
      &lt;/div&gt;
    )
  }
}
export default App;

When the cursor moves on the screen, the component is<p>Its coordinates are displayed in .

The question now is: How do we reuse this behavior in another component? To put it another way, if another component needs to know the mouse location, can we encapsulate this behavior so that we can easily share it with other components?

render prop is a function prop that tells the component what content it needs to render.

src/

import React from 'react'
import ReactDOM  from 'react-dom/client'
​
// When introduced, the suffix name can be omitted and can be configured in webpack// import App from './01-App-parent-child'
// import App from './02-App-parent-child-value'
// import App from './03-App-parent-child-value-default'
// import App from './04-App-parent-child-value-default-type'
// import App from './05-App-props-children'
// import App from './06-App-mutiple-props-children'
// import App from './07-App-mouse-tracker'
import App from './08-App-render-props'
​
const root = (('root'))
​
(&lt;App /&gt;)

src/

import { Component } from 'react'
// Rendering property sharing component status// On the component (Mouse) that needs to be shared, add a render custom property, which is a custom function// Return the component (Cat) that needs to be shared with within the custom function (Cat)// Inside the component (Mouse) that needs to be shared, it can be called through () or (), and the parameters are the status that needs to be shared.// Then, within the function that defines the custom render attribute, a parameter will be received, and the parameter will be passed through the returned component (Cat)​
const Cat = ({ mounsePointer }) =&gt; {
  return (
    &lt;div style={ {
      position: 'fixed',
      left: ,
      top: ,
      backgroundColor: '#ccc',
      width: 100,
      height: 100
    } }&gt;&lt;/div&gt;
  )
}
​
class Mounse extends Component {
  state = { x: 0, y: 0 }
​
  render () {
    return (
      &lt;div style={ { width: '100vw', height: '100vh', backgroundColor: '#f66'} } onMouseMove = { (event) =&gt; {
        (event)
        // Modify the initialization value        ({
          x: ,
          y: 
        })
      } }&gt;
        &lt;p&gt;
          The current mouse position is,x:{  },y: {  }
​
        &lt;/p&gt;
        { () }
      &lt;/div&gt;
    )
  }
}
class App extends Component {
  render () {
    return (
      &lt;div&gt;
        {/* &lt;Mounse&gt;&lt;/Mounse&gt;
        &lt;Cat &gt;&lt;/Cat&gt; */}
        &lt;Mounse render = { (mounsePointer) =&gt; {
          return &lt;Cat mounsePointer = { mounsePointer }/&gt;
        } }&gt;&lt;/Mounse&gt;
      &lt;/div&gt;
    )
  }
}
​
export default App

This case actually completes the child component passing values ​​to the parent component in react

Summarize

With Render Props, we can easily share the state or behavior of components with other components, thereby improving code reusability and maintainability. This article shows how to use Render Props to implement state sharing through a specific example - the mouse position tracking component. I hope this article can help readers better understand and apply Render Props and improve the development efficiency of React applications.

This is the end of this article about the Props features and applications in React. For more information about React Props features, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!