[React] Make Compound React Components Flexible
Our current compound component implementation is great, but it's limited in that users cannot render the structure they need. Let's allow the user to have more flexibility by using React context to share the implicit state to our child <Toggle/> components. We will walk through using React's official context API with React.createContext and use the given Provider and Consumer components to share state implicitly between our compound components giving our users the flexibility they need out of our component.
When we use compound component, we are also using React.Children.map:
return React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
on: this.state.on,
toggle: this.toggle,
})
})
React.Children.map + this.props.children limits what compound compoment should found some structure, you can do:
return (
<Toggle onToggle={onToggle}>
<Toggle.On>The button is on</Toggle.On>
<Toggle.Button />
<Toggle.Off>The button is off</Toggle.Off>
</Toggle>
)
But app will break if you do:
return (
<Toggle onToggle={onToggle}>
<Toggle.On>The button is on</Toggle.On>
<Toggle.Button />
<div>
<Toggle.Off>The button is off</Toggle.Off>
</div>
</Toggle>
)
Because this.props.children will looking for direct child inside <Toggle>, if we add <div> wrapper, it will break the structure, then code won't work.
So we need more flexable code, to achieve that we can use Context.
// Flexible Compound Components with context import React from 'react'
import {Switch} from '../switch' const ToggleContext = React.createContext() class Toggle extends React.Component { static On = ({children}) => (
<ToggleContext.Consumer>
{contextValue => (contextValue.on ? children : null)}
</ToggleContext.Consumer>
)
static Off = ({children}) => (
<ToggleContext.Consumer>
{contextValue => (contextValue.on ? null : children)}
</ToggleContext.Consumer>
)
static Button = props => (
<ToggleContext.Consumer>
{contextValue => (
<Switch
on={contextValue.on}
onClick={contextValue.toggle}
{...props}
/>
)}
</ToggleContext.Consumer>
)
state = {on: false}
toggle = () =>
this.setState(
({on}) => ({on: !on}),
() => this.props.onToggle(this.state.on),
)
render() { return (
<ToggleContext.Provider
value={{
on: this.state.on,
toggle: this.toggle,
}}
>
{this.props.children}
</ToggleContext.Provider>
)
}
} function Usage({
onToggle = (...args) => console.log('onToggle', ...args),
}) {
return (
<Toggle onToggle={onToggle}>
<Toggle.On>The button is on</Toggle.On>
<Toggle.Off>The button is off</Toggle.Off>
<div>
<Toggle.Button />
</div>
</Toggle>
)
}
Usage.title = 'Flexible Compound Components' export {Toggle, Usage as default}
[React] Make Compound React Components Flexible的更多相关文章
- [React] Render Text Only Components in React 16
In this session we create a comment component to explore how to create components that only render t ...
- [React] Recompose: Theme React Components Live with Context
SASS Bootstrap allows us to configure theme or branding variables that affect all components (e.g. P ...
- [react] 细数 React 的原罪
Props & onChange 的原罪 .「props & onChange 接口规范」它不是一个典型的「程序接口规范」. 当你拿到一个可视组件的 ref,却没有类似 setProp ...
- React笔记:React基础(2)
1. JSX JSX是一种拥有描述UI的JavaScript扩展语法,React使用这种语法描述组件的UI. 1.1 基本语法 JSX可以嵌套多个HTML标签,可以使用大部分符号HTML规范的属性. ...
- react初探索--react + react-router + ant-design 后台管理系统配置
首先确认安装了node环境,Node >= 6. 如果对react 及 ant-design 一无所知,建议去阅读下api文档,react 可以在 codePen 在线练习. react Api ...
- react新特性 react hooks
本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...
- react聊天室|react+redux仿微信聊天IM实例|react仿微信界面
一.项目概况 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开 ...
- WHAT IS THE DIFFERENCE BETWEEN REACT.JS AND REACT NATIVE?
Amit Ashwini - 09 SEPTEMBER 2017 React.js was developed by Facebook to address its need for a dynami ...
- 七天接手react项目 系列 —— react 脚手架创建项目
其他章节请看: 七天接手react项目 系列 react 脚手架创建项目 前面我们一直通过 script 的方式学习 react 基础知识,而真实项目通常是基于脚手架进行开发. 本篇首先通过 reac ...
随机推荐
- IE主页被恶意修改处理办法
HKEY_USERS/.DEFAULT/Software/Policies/Microsoft/Internet Explorer/Control Panel 下的DWORD值“homepage”的键 ...
- 分组密码_计数器(CTR)模式_原理及java实现
一.原理: CTR模式是一种通过将逐次累加的计数器进行加密来生成密钥流的流密码,在CTR模式中,每个分组对应一个逐次累加的计数器,并通过对计数器进行加密来生成密钥流.最终的密文分组是通过将计数器加密得 ...
- bind - 将一个名字和一个套接字绑定到一起
SYNOPSIS 概述 #include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, struct s ...
- ssd训练自己的数据集
1.在ssd/caffe/data下创建VOC2007的目录,将ssd/caffe/data/VOC0712里的create_data.sh.create_list.sh和labelmap_voc.p ...
- 16.04 下 ufw 防火墙的的开启、禁用、开放端口、关闭端口
16.04 下的 ufw 防火墙相关操作使用ufw命令.通过ufw --help可以查看所有相关命令. 打开防火墙 sudo ufw enable 重启防火墙 sudo ufw reload 打开指定 ...
- LAME的“命令行”
VBR 编码 (强烈推荐) Alt Preset Extreme (平均256kbps) 我们有时在网上可以看到".LAME-APX." 就是这种形式,我们也可以在文件名中包含这个 ...
- 用PHP的GD库画五星红旗来玩玩
1 header("Content-Type:image/jpeg"); $img=imagecreatetruecolor(999,667); $color=imagecolor ...
- group 和 gshadow
group组文件 位置:/etc/group 作用:存放用户的分组信息 使用 /etc/group 命令查看时,得到的数据如下: 分析上图,可以得到以下结果 第1个字段:组名 默认组名与用户名名称一样 ...
- 监听服务器 重启apache
import requests import os import time url = 'http://www.ydyigo.com/findPwd.php' def get_server_statu ...
- CSS九宫格样式
CSS .main>div { width: 14%; min-width: 160px; padding: 2%; height: 60px; border: 1px solid #f4f4f ...