[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 ...
随机推荐
- myslq 5.7 root 默认密码
sudo sumysqld_safe --skip-grant-tables --skip-networking & UPDATE mysql.user SET password=PASSWO ...
- 查看DNS、IP、Mac等
A.Win98:winipcfg B.Win2000以上:Ipconfig/all C.NSLOOKUP:如查看河北的DNS C:\\>nslookup Default Server: ...
- CAD参数绘制文字(网页版)
在CAD设计时,需要绘制文字,用户可以设置设置绘制文字的高度等属性. 主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOUBLE dPosX ...
- 第2节 mapreduce深入学习:15、reduce端的join算法的实现
reduce端的join算法: 例子: 商品表数据 product: pidp0001,小米5,1000,2000p0002,锤子T1,1000,3000 订单表数据 order: pid ...
- vue列表排序实现中的this问题
最近在看vue框架的知识,然后其中有个例子中的this的写法让我很疑惑 <!DOCTYPE html> <html> <head> <meta charset ...
- get data from splunk
link: http://dev.splunk.com/view/python-sdk/SP-CAAAER5 download SDK & setup with python code: im ...
- git命令初级
git是开源的分布式版本控制系统,分布式主要区别于集中式代表CVS(Concurrent Version System,遵从C/S架构,同步比较笨拙.)和SVN(Subversion),linux开发 ...
- PHP中设置session过期的时间
如何严格限制session在30分钟后过期!1.设置客户端cookie的lifetime为30分钟:2.设置session的最大存活周期也为30分钟:3.为每个session值加入时间戳,然后在程序调 ...
- 树莓派 - 通过sysfs操控GPIO
点亮或熄灭LED 硬件上,一个LED灯接在pi的Pin-25. 该引脚为BCM的GPIO26 $ gpio readall +-----+-----+---------+------+---+--- ...
- Far Relative’s Problem (贪心 计算来的最多客人)
Description Famil Door wants to celebrate his birthday with his friends from Far Far Away. He has n ...