-
Notifications
You must be signed in to change notification settings - Fork 4
/
solution.js
93 lines (84 loc) · 2.92 KB
/
solution.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
////////////////////////////////////////////////////////////////////////////////
// Exercise:
//
// Currently in React, there is no way to have local state on a component except by using a class component.
// Using this.setState is a very basic React concept that most React developers interact with everyday.
// Why don't we try something a little different. Let's compose these components further.
// With the tabs example we have below, let's use Recompose to break apart the functionality from
// UI by following the container/presentational component pattern.
// - Convert the Tabs component into a Stateless functional component. Abstract the methods and state into HoCs (Hint: use withState and withHandlers)
// - Convert Tab component into a stateless functional component. Abstract the method into an HoC. (Hint: use withHandlers)
//
// Don't forget to refer to the recompose docs!
// https://github.com/acdlite/recompose/blob/master/docs/API.md
//
////////////////////////////////////////////////////////////////////////////////
import React from 'react'
import pt from 'prop-types'
import { compose, withState, withHandlers } from 'recompose'
import classnames from 'classnames'
const TabComponent = ({ content, style, onClick, isActive }) => {
const classNames = classnames('tab', { active: isActive })
return (
<div className={classNames} onClick={onClick}>
{content}
</div>
)
}
TabComponent.propTypes = {
content: pt.string.isRequired,
onClick: pt.func.isRequired,
isActive: pt.bool,
}
const Tab = withHandlers({
onClick: ({ index, onClickUpdateIndex }) => () => onClickUpdateIndex(index),
})(TabComponent)
const TabsComponent = ({ data, activeTabIndex, updateActiveTabIndex }) => {
const tabs = data.map((tab, index) => {
const isActive = index === activeTabIndex
return (
<Tab
key={tab.id}
index={index}
isActive={isActive}
content={tab.label}
onClickUpdateIndex={updateActiveTabIndex}
/>
)
})
const activeTab = data[activeTabIndex]
const content = activeTab && activeTab.content
return (
<div className="tabs">
{tabs}
<div className="panel">
{content}
</div>
</div>
)
}
TabsComponent.propTypes = {
data: pt.array.isRequired,
activeTabIndex: pt.number.isRequired,
updateActiveTabIndex: pt.func.isRequired,
}
const Tabs = compose(
withState('activeTabIndex', 'updateActiveTabIndex', 0),
withHandlers({
selectTabIndex: ({ updateActiveTabIndex }) => activeTabIndex => {
updateActiveTabIndex(activeTabIndex)
},
}),
)(TabsComponent)
const countries = [
{ id: 1, label: 'USA', content: 'Land of the Free, Home of the brave' },
{ id: 2, label: 'Brazil', content: 'Sunshine, beaches, and Carnival' },
{ id: 3, label: 'Russia', content: 'World Cup 2018!' },
]
const App = () => (
<div className="state-as-props">
<h1>Countries</h1>
<Tabs data={countries} />
</div>
)
export { App as Solution }