mirror of
https://github.com/kay-is/react-from-zero.git
synced 2026-04-24 03:00:06 -04:00
138 lines
3.4 KiB
HTML
138 lines
3.4 KiB
HTML
<!doctype html>
|
|
|
|
<title>12 Component Refactor - React From Zero</title>
|
|
|
|
<script src="https://unpkg.com/react@16.4.0/umd/react.development.js"></script>
|
|
<script src="https://unpkg.com/react-dom@16.4.0/umd/react-dom.development.js"></script>
|
|
<script src="https://unpkg.com/create-react-class@15.6.3/create-react-class.js"></script>
|
|
<script src="https://unpkg.com/prop-types@15.6.1/prop-types.js"></script>
|
|
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
|
|
<div id="app"></div>
|
|
|
|
<script type="text/babel">
|
|
// Refactoring is another thing that is nice with React
|
|
// First we'll talk about refactoring one component into another
|
|
// if you're lucky, you can just change the implementation of a component
|
|
// and don't need to change anything at the call-site
|
|
|
|
// We start with a component that renders records somehow
|
|
function ViewBefore(props) {
|
|
return (
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Room</th>
|
|
<th>People</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{props.rooms.map(function(room, k) {
|
|
return <tr key={k}>
|
|
<td>{room.name}</td>
|
|
<td>{room.people}</td>
|
|
</tr>
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
)
|
|
}
|
|
|
|
// The component has a simple props-interface
|
|
ViewBefore.propTypes = {
|
|
rooms: PropTypes.array.isRequired,
|
|
}
|
|
|
|
// Now we switch out the implementation with something more complicated
|
|
function ViewAfter(props) {
|
|
return (
|
|
<div>
|
|
{props.rooms.map(function(room, k) {
|
|
var barStyle = {
|
|
display: "inline-block",
|
|
background: "lightgrey",
|
|
width: room.people * 25,
|
|
}
|
|
return <div key={k}>
|
|
{room.people > 0
|
|
? <span style={barStyle}>{room.people} People</span>
|
|
: <span>0 People</span>
|
|
}
|
|
<span> in {room.name}</span>
|
|
</div>
|
|
})}
|
|
</div>
|
|
)
|
|
}
|
|
// We keep the props-interface the same
|
|
ViewAfter.propTypes = {
|
|
rooms: PropTypes.array.isRequired,
|
|
}
|
|
|
|
// We could also switch it with something more dynamic
|
|
var ViewDynamic = createReactClass({
|
|
|
|
// We still keep the props-interface the same
|
|
propTypes: {
|
|
rooms: PropTypes.array.isRequired,
|
|
},
|
|
|
|
getInitialState: function() {
|
|
return {currentRoom: 0}
|
|
},
|
|
|
|
componentDidMount() {
|
|
var component = this
|
|
var props = this.props
|
|
|
|
this.interval = setInterval(function() {
|
|
var currentRoom = component.state.currentRoom < props.rooms.length - 1
|
|
? component.state.currentRoom + 1
|
|
: 0
|
|
component.setState({currentRoom: currentRoom})
|
|
}, 1000)
|
|
},
|
|
|
|
componentWillUnmount() {
|
|
clearInterval(this.interval)
|
|
},
|
|
|
|
render: function() {
|
|
var room = this.props.rooms[this.state.currentRoom]
|
|
|
|
return (
|
|
<span style={{color: this.state.color}}>
|
|
Room <b>{room.name}</b> has <b>{room.people}</b> People.
|
|
</span>
|
|
)
|
|
},
|
|
|
|
})
|
|
|
|
// Some data
|
|
var rooms = [
|
|
{name:"Office", people: 10},
|
|
{name:"Kitchen", people: 15},
|
|
{name:"Floor", people: 3},
|
|
{name:"Bathroom", people: 0},
|
|
]
|
|
|
|
// As we can see the components can be used exactly the same
|
|
// If we copy the implementation of ViewAfter into ViewBefore,
|
|
// everything keeps working
|
|
var reactElement =
|
|
<div style={{margin: "auto", width: 500}}>
|
|
|
|
<h3>Before the refactor</h3>
|
|
<ViewBefore rooms={rooms}/>
|
|
|
|
<h3>After the refactor</h3>
|
|
<ViewAfter rooms={rooms}/>
|
|
|
|
<h3>Dynamic refactor</h3>
|
|
<ViewDynamic rooms={rooms}/>
|
|
|
|
</div>
|
|
|
|
ReactDOM.render(reactElement, document.getElementById("app"))
|
|
</script> |