Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React component patterns
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Dawid Jankowiak
October 17, 2017
Programming
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React component patterns
Dawid Jankowiak
October 17, 2017
More Decks by Dawid Jankowiak
See All by Dawid Jankowiak
React Component Patterns WDI version
jankowiakdawid
1
58
Other Decks in Programming
See All in Programming
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
570
React本体のコードリーディング
high_g_engineer
1
130
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
250
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
210
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
200
AI時代に設計が 最大の生産性レバーになる 意図駆動開発とデータを消さない設計|Don't Delete Your Data or Your Intent — Design as the Deepest Lever in the AI Era
tomohisa
1
670
torikago - Ruby::Boxで照らすモジュラモノリスの実行境界
se4weed
1
340
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
140
自動化したのに回らないテスト運用の壁ーAI時代の品質責任と生産性
mfunaki
0
120
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
240
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
130
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
180
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
55
8.2k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
360
Designing Experiences People Love
moore
143
24k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Into the Great Unknown - MozCon
thekraken
41
2.7k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Building an army of robots
kneath
306
46k
Chasing Engaging Ingredients in Design
codingconduct
0
260
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
The Curious Case for Waylosing
cassininazir
1
450
Transcript
@jankowiak_dawid
Higher Order Component Function as a Child (Render Function) Compound
Components Reducer Component
Connect(react-redux) Recompose Redux-Form Function that takes a component as a
parameter and returns another component
const ApplicantInfoPage = ({ data, isLoading, error }) => {...};
export default withFetch( ownProps => `/api/applicants/${ownProps.match.props.id}` )(ApplicantInfoPage);
const withFetch = urlGetter => BaseComponent => class WithFetch extends
React.Component { state = { isLoading: true, error: null, data: null }; static displayName = `WithFetch(${wrapDisplayName( BaseComponent )})`;
componentDidMount() { axios .get(urlGetter(this.props)) .then(({ data }) => this.setState({ data,
isLoading: false })) .catch(error => this.setState({ error, isLoading: false })); }
render() { if (this.state.isLoading === true) { return <Loading />;
} if (this.state.error !== null) { return <ErrorPanel />; } return <BaseComponent {...this.props} data={this.state.data} />; } };
Lets you mix behaviours Simple to use Composable (like regular
function composition) Applicable before use (cannot be used in render function) Refs aren’t passed through Static methods must be copied over
https://github.com/acdlite/recompose/blob/master/docs/performance.md https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750 More on the topic:
Downshift React-Motion React-Router v4 react-virtualized Passing a function to a
component (as a prop or children of component) that tells it what to render
<Paging items={itemsArray} itemsPerPage={10} render={item => ( <div>{item.name}</div> )} />; <Paging
items={itemsArray} itemsPerPage={10} > {item => ( <div>{item.name}</div> )} </Paging>;
class Paging extends Component { … render() { const items
= this.getItems(); return ( <div> {items.map(this.prop.render)} {this.renderButtons()} </div> ); } } class Paging extends Component { … render() { const items = this.getItems(); return ( <div> {items.map(this.prop.children)} {this.renderButtons()} </div> ); } }
Used as regular components Simple to implement Dynamic in nature
Nesting (hell?) Returning large component tree may introduce performance problems
https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce https://blog.kentcdodds.com/introducing-downshift-for-react-b1de3fca0817 http://americanexpress.io/faccs-are-an-antipattern/ More on the topic:
Table List Accordion Tabs Carousel Components that share the local
state
<Carousel> <Item> <img src="some-nsfw.png" /> </Item> <Item active> <h1>Bold title</h1>
</Item> </Carousel>;
const Item = ({ children, isHighlighted }) => ( <section
className={isHighlighted ? 'highlighted' : ''}> {children} </section> )
class Carousel extends Component { state = { activeIndex: null
}; render() { const { state: { activeIndex }, props: { children } } = this; return ( <div> <PrevButton onClick={this.handlePreviewClick()} /> {this.getActiveItem(children, activeIndex)} {this.getDottedMenu(children)} <NextButton onClick={this.handleNextClick()} /> </div> ); }
... getActiveItem(items, activeIndex) { const item = React.Children.toArray(items).find((item, index) =>
{ if (activeIndex !== null) return index === activeIndex; return item.props.active === true; }); return React.cloneElement(item, { isHighlighted: true }); } ...
... getDottedMenu(items) { return React.Children.map(items, (item, index) => <DotMenuItem onClick={()
=> this.setState({ activeIndex: index })} /> ); } }
Enables creating general purpose sharable components Require a lot of
imperative manual work Local state harder to manage from outside
React.Children.toArray React.Children.map React.cloneElement React.Children.count React.Children.only React.Children.forEach React.isValidElement
http://mxstbr.blog/2017/02/react-children-deepdive/ https://youtu.be/hEGg-3pIHlE http://developingthoughts.co.uk/using-the-react-children-api/ More on the topic:
Component with State Machine, inspired by ReasonReact, feels like Redux
in component Rediscovered from recompose (bet all familiar with redux had this idea)
class Counter extends ReducerComponent { state = { count: 0
}; increment(_e) { return "increment"; } decrement(_e) { return "decrement"; }
reducer(state, action) { switch (action) { case "increment": return {
count: state.count + 1 }; case "decrement": return { count: state.count - 1 }; } }
render() { return ( <div> Counter: {this.state.count} <button onClick={this.dispatch(this.increment)}>+</button> <button
onClick={this.dispatch(this.decrement)}>-</button> </div> ); } }
class ReducerComponent extends React.Component { reducer(state, action) { return state;
} dispatch(actionCreator) { return (...eventArgs) => { this.setState((prevState, _props) => { this.reducer(prevState, actionCreator(...eventArgs)); }); }; } }
Simple to manage a complex state For small apps/complex local
states Requires familiarity with a reducing state Not needed when other State libraries are present (Redux/MobX)
https://twitter.com/_developit/status/905250269306474497 https://twitter.com/jaredpalmer/status/905170062679662594 https://twitter.com/_developit/status/905427773891727360 https://reasonml.github.io/reason-react/docs/en/state-actions-reducer.html More on the topic:
Higher Order Component Lets you add behaviour to components Function
As a Child (Render Function) Lets you focus on what will be rendered Compound Components Lets you create groups of components with shared state Reducer Component Lets you manage a component state in a single place
@jankowiak_dawid