惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
LangChain Blog
月光博客
月光博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园_首页
T
Tailwind CSS Blog
P
Proofpoint News Feed
雷峰网
雷峰网
D
Darknet – Hacking Tools, Hacker News & Cyber Security
IT之家
IT之家
V
Vulnerabilities – Threatpost
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
S
Schneier on Security
Security Archives - TechRepublic
Security Archives - TechRepublic
L
Lohrmann on Cybersecurity
V
Visual Studio Blog
云风的 BLOG
云风的 BLOG
WordPress大学
WordPress大学
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
博客园 - 叶小钗
F
Full Disclosure
大猫的无限游戏
大猫的无限游戏
Latest news
Latest news
S
SegmentFault 最新的问题
C
Cyber Attacks, Cyber Crime and Cyber Security
Google Online Security Blog
Google Online Security Blog
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
腾讯CDC
L
LINUX DO - 最新话题
Google DeepMind News
Google DeepMind News
P
Privacy International News Feed
I
InfoQ
F
Fortinet All Blogs
Vercel News
Vercel News
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
T
Tenable Blog
B
Blog RSS Feed

Maxime Heckel's Blog

On Rendering the Sky, Sunsets, and Planets - The Blog of Maxime Heckel Shades of Halftone - The Blog of Maxime Heckel Field Guide to TSL and WebGPU - The Blog of Maxime Heckel On Shaping Light: Real-Time Volumetric Lighting with Post-Processing and Raymarching for the Web - The Blog of Maxime Heckel Speaking at Figma Config 2025 - The Blog of Maxime Heckel Post-Processing Shaders as a Creative Medium - The Blog of Maxime Heckel On Crafting Painterly Shaders - The Blog of Maxime Heckel The Art of Dithering and Retro Shading for the Web - The Blog of Maxime Heckel Moebius-style post-processing and other stylized shaders - The Blog of Maxime Heckel Shining a light on Caustics with Shaders and React Three Fiber - The Blog of Maxime Heckel Real-time dreamy Cloudscapes with Volumetric Raymarching - The Blog of Maxime Heckel Painting with Math: A Gentle Study of Raymarching - The Blog of Maxime Heckel Building a magical AI-powered semantic search from scratch - The Blog of Maxime Heckel Beautiful and mind-bending effects with WebGL Render Targets - The Blog of Maxime Heckel Refraction, dispersion, and other shader light effects - The Blog of Maxime Heckel The magical world of Particles with React Three Fiber and Shaders - The Blog of Maxime Heckel The Study of Shaders with React Three Fiber - The Blog of Maxime Heckel Building a Design System from scratch - The Blog of Maxime Heckel Everything about Framer Motion layout animations - The Blog of Maxime Heckel Building a Vaporwave scene with Three.js - The Blog of Maxime Heckel Cubic Bézier: from math to motion - The Blog of Maxime Heckel First steps with GPT-3 for frontend developers - The Blog of Maxime Heckel Building the perfect GitHub CI workflow for your frontend team - The Blog of Maxime Heckel Migrating to Next.js - The Blog of Maxime Heckel Static Tweets with MDX and Next.js - The Blog of Maxime Heckel Advanced animation patterns with Framer Motion - The Blog of Maxime Heckel Scrollspy demystified - The Blog of Maxime Heckel The Power of Composition with CSS Variables - The Blog of Maxime Heckel My first failed SwiftUI project - The Blog of Maxime Heckel Guide to creating animations that spark joy with Framer Motion - The Blog of Maxime Heckel Using Shortcuts and serverless to build a personal Apple Health API - The Blog of Maxime Heckel SEO mistakes I've made and how I fixed them - The Blog of Maxime Heckel Going native: SwiftUI from the perspective of a React developer - The Blog of Maxime Heckel Build your own preview deployment service - The Blog of Maxime Heckel The little guide to CI/CD for frontend developers - The Blog of Maxime Heckel Immigrating to the US - The Blog of Maxime Heckel The physics behind spring animations - The Blog of Maxime Heckel Generate screenshots of your code with a serverless function - The Blog of Maxime Heckel How to use Framer Motion with Emotion styled-components - The Blog of Maxime Heckel Data Fetching with NextJS: What I learned - The Blog of Maxime Heckel Learning in public - The Blog of Maxime Heckel Fixing the dark mode flash issue on server rendered websites - The Blog of Maxime Heckel How to fix NPM link duplicate dependencies issues - The Blog of Maxime Heckel Running scheduled cross-browser end-to-end tests on Github CI - The Blog of Maxime Heckel How I built my first custom ESLint rule - The Blog of Maxime Heckel React Lazy: a take on preloading views - The Blog of Maxime Heckel Automated UI accessibility testing with Cypress - The Blog of Maxime Heckel Building a GraphQL wrapper for the Docker API - The Blog of Maxime Heckel Switching off the lights - Adding dark mode to your React app - The Blog of Maxime Heckel Getting started with Typescript on Gatsby - The Blog of Maxime Heckel Rebuilding Redux with Hooks and Context - The Blog of Maxime Heckel Asynchronous rendering with React - The Blog of Maxime Heckel Using Flow generics to type generic React components - The Blog of Maxime Heckel How to efficiently type your styled-components with Flow - The Blog of Maxime Heckel How I got started with Kubernetes on GKE - The Blog of Maxime Heckel React sub-components Part 3: Whitelisting sub-components with flow - The Blog of Maxime Heckel React sub-components - The Blog of Maxime Heckel Running Golang tests with Jest - The Blog of Maxime Heckel No title No title
React sub-components Part 2: Using the new Context API - The Blog of Maxime Heckel
Maxime Heckel · 2018-04-17 · via Maxime Heckel's Blog

To fully understand this post, please read my original post about React sub-components first.

I’ve received a lot of good feedback after publishing my first article about React sub-components, however, some of them got me thinking about how I could further improve the sub-components pattern in order to make it easier to read and use.

The flaws of the current pattern

Here are some the critiques I got back from some readers:

  • Having to import findByType for every component using sub-components is annoying

  • It is hard to compose or extend a sub-component to handle specific cases

  • It’s not the most readable

  • We could easily put the wrong data within the sub-component, it is not aware about what we’re trying to render within it

While I agreed with all these statements, I couldn’t find an elegant way to address them without making the component difficult to use. However one day, one user from the Reactiflux community mentioned that using contexts would remove the necessity of using the findByType util within each sub-component; which obviously got me curious. Moreover, I was hearing a lot about the upcoming new Context API in React 16.3.0 and I thought that this would be a great way to start experimenting a bit with this new functionality.

What is in the new Context API?

Up until now, I’ve always thought contexts in React were hard to use, and it never felt natural to me to implement components using them except in some rare higher-order components. Plus it always fell in the category of “experimental API” so I’ve never had enough confidence in it to use it for a lot of production components.

The new API, however, takes a new approach to contexts and makes the feature more accessible. It is available in React 16.3.0, you can read a lot more about it and how to use it in this article. For the purpose of this post, I’ll just keep it short and explain the 3 main items that make up this new pattern:

  • React.CreateContext: a function that returns an object with a Provider and a Consumer

  • Provider: a component that accepts a value prop

  • Consumer: a Function as Child component with the value from the Provider as a parameter

With these new items, we’ll see that it is possible to create a better sub-component pattern that answers all the flaws stated in the first part.

How to build a sub-component like pattern with the context API

For this part, we’ll try to build the same Article component that we’ve built in my first post, but this time using contexts.

In order to achieve this, we’ll need to create an ArticleContext. This will give us an ArticleContext.Provider component that will be our main parent, which we’ll rename Article, and an ArticleContext.Consumer, which will help us build all the sub-components we need.

Let’s start this example by implementing a Title sub-component:

1

import React from 'react';

4

const ArticleContext = React.createContext();

9

<ArticleContext.Consumer>

10

{({ title, subtitle }) => (

11

<div style={{ textAlign: 'center' }}>

13

<div style={{ color: '#ccc' }}>

18

</ArticleContext.Consumer>

23

const Article = (props) => {

25

<ArticleContext.Provider {...props}>

27

</ArticleContext.Provider>

33

export default Article;

The example above shows how we can leverage Consumers and Providers to obtain the same sub-component pattern as we had in the first example of my previous article. If you compare this code in the link with the code above, you can see that the latter feels way simpler. Indeed, thanks to the new Context API, there is no need to build and use the findByType util. Additionally, we don’t rely on the displayName or name property of the sub-component to know how to render them.

In the code below, we can see that the resulting Article component is much easier to use. Instead of passing children to the Title sub-component, we just need to pass them in the value prop of Article, which will make them available to every Consumer of the Article context (i.e. to every sub-component defined as a Consumer of this context).

1

import React, { Component } from 'react';

2

import Article from './Article';

4

class App extends Component {

8

title: <h1>React sub-components with</h1>,

10

<div>Lets make simpler and more flexible React components</div>

17

const { value } = this.state;

19

<Article value={value}>

Moreover, if we want to wrap Article.Title in another div or component, we can now do that as well. Given that the implementation of the findByType util in my first post was relying on the direct children of Article , sub-components were restricted to be direct children and nothing else, which is not the case with this new way of doing sub-components.

Note: You can see above that my value object passed to the provider is set to the parent’s state. This is to avoid creating a new object for value all the time which will trigger a re-render of Provider and all of the consumers. See https://reactjs.org/docs/context.html#caveats

Additionally, we can make the piece of code above look even better. By simply exporting the Title functional component in Article.js we can give up the <Article.Title/> notation and simply use instead <Title/>.

1

import React, { Component } from 'react';

2

import Article, { Title } from './Article';

4

class App extends Component {

8

title: <h1>React sub-components with</h1>,

10

<div>Lets make simpler and more flexible React components</div>

16

const { value } = this.state;

18

<Article value={value}>

This is purely aesthetic though, and I personally prefer the first implementation. It gives more context about where a given sub-component comes from and with which parent component it can be used, and also avoids duplicated name issues.

Caveats

When showing this new pattern to some other developers who were familiar with using the one described in my first article I got one critique: it’s not possible to whitelist children anymore; anything can go within the parent component. While this new implementation is more flexible, the first one was able to restrict the children of a component to only its sub-components. There are multiple ways to fix this, but so far the only one I’ve explored is by using flow. I’ll detail the process in my next article.

Full implementation

In the code snippets below, you will find:

  • The full Article component code and all its sub-components in Article.js

  • An example App.js where you can see how we use the full component and sub-components

1

import React from 'react';

4

const ArticleContext = React.createContext();

9

<ArticleContext.Consumer>

10

{({ title, subtitle }) => (

11

<div style={{ textAlign: 'center' }}>

13

<div style={{ color: '#ccc' }}>

18

</ArticleContext.Consumer>

22

const Metadata = () => {

24

<ArticleContext.Consumer>

25

{({ author, date }) => (

29

justifyContent: 'space-between',

36

</ArticleContext.Consumer>

40

const Content = () => {

42

<ArticleContext.Consumer>

44

<div style={{ width: '500px', margin: '0 auto' }}>{content}</div>

46

</ArticleContext.Consumer>

51

const Article = (props) => {

53

<ArticleContext.Provider {...props}>

55

</ArticleContext.Provider>

60

Article.Metadata = Metadata;

61

Article.Content = Content;

63

export default Article;

1

import React, { Component } from 'react';

2

import Article from './Article';

5

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

8

class App extends Component {

12

title: <h1>React sub-components with</h1>,

14

<div>Lets make simpler and more flexible React components</div>

16

author: 'Maxime Heckel',

17

date: <i>April 2018</i>,

18

content: <p>{text}</p>,

23

const { value } = this.state;

25

<Article value={value}>

28

<div style={{ width: '500px', margin: '80px auto' }}>

If you feel like playing with this pattern I’ve made the example of this article available on Github here, you can set up the dockerized project using docker-compose build && docker-compose up, or just run yarn && yarn start if you want to run it directly on your machine.