mirror of
https://github.com/kay-is/react-from-zero.git
synced 2026-04-24 03:00:06 -04:00
150 lines
3.9 KiB
HTML
150 lines
3.9 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 we're lucky, we can just change the components implementation
|
|
// 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.arrayOf(PropTypes.shape({
|
|
name: PropTypes.string.isRequired,
|
|
people: PropTypes.number.isRequired
|
|
})).isRequired
|
|
}
|
|
|
|
// We switch out the implementation with something more complex
|
|
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.arrayOf(PropTypes.shape({
|
|
name: PropTypes.string.isRequired,
|
|
people: PropTypes.number.isRequired
|
|
})).isRequired
|
|
}
|
|
|
|
// We could also switch it with something more dynamic
|
|
var ViewDynamic = createReactClass({
|
|
// We still keep the props-interface the same
|
|
propTypes: {
|
|
rooms: PropTypes.arrayOf(PropTypes.shape({
|
|
name: PropTypes.string.isRequired,
|
|
people: PropTypes.number.isRequired
|
|
})).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> |