Last active
February 7, 2018 00:05
-
-
Save chadwithuhc/4c0ae8a15891e3be3570fbf6efcf2e61 to your computer and use it in GitHub Desktop.
React Refactors for Clean Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Challenge: Refactor the `render()` method with declare all variables at top | |
render() { | |
return ( | |
<li> | |
<div className="profile-card"> | |
<header className="profile-header" onClick={this.toggleClass}> | |
<img src={this.props.profile.image} alt={this.props.profile.name} /> | |
<h2>{this.props.profile.name}</h2> | |
</header> | |
<section | |
className={ | |
this.state.active ? "skills-container hidden" : "skills-container" | |
} | |
> | |
<h4>Skills</h4> | |
<ul className="skills-list"> | |
{this.props.profile.skills.map(skill => { | |
return <li key={skill}>{skill}</li> | |
})} | |
</ul> | |
</section> | |
</div> | |
</li> | |
) | |
} | |
// Refactors to -> | |
// 1. Replace all `this.props.profile` instances to be just `profile` to allow for readability | |
// We use destructuring to accomplish this | |
// Now we know where the `profile` is coming from when we are referring to it | |
// 2. Replace the full `this.state.active` with the destructured value | |
// If we need to refactor to swap some props for state, we only change it in one place | |
render() { | |
const { profile } = this.props | |
const { active } = this.state | |
return ( | |
<li> | |
<div className="profile-card"> | |
<header className="profile-header" onClick={this.toggleClass}> | |
<img src={profile.image} alt={profile.name} /> | |
<h2>{profile.name}</h2> | |
</header> | |
<section | |
className={ | |
active ? "skills-container hidden" : "skills-container" | |
} | |
> | |
<h4>Skills</h4> | |
<ul className="skills-list"> | |
{profile.skills.map(skill => { | |
return <li key={skill}>{skill}</li> | |
})} | |
</ul> | |
</section> | |
</div> | |
</li> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Challenge: We're try to leave the `constructor()` out since we can achieve the same result with syntactical sugar | |
export class ProfileCard extends React.Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
active: true | |
} | |
this.toggleClass = this.toggleClass.bind(this) | |
} | |
toggleClass() { | |
var currentState = this.state.active | |
this.setState({ active: !currentState }) | |
} | |
// ... | |
} | |
// Reactors to -> | |
// 1. Move `state` to a property on the Class | |
// 2. Bind `this` with the syntactical sugar available, setting `toggleClass` to an anonymous function with `this` bound | |
export class ProfileCard extends React.Component { | |
state = { | |
active: true | |
} | |
toggleClass = () => { | |
var currentState = this.state.active | |
this.setState({ active: !currentState }) | |
} | |
// ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Challenge: Refactor using ES6 shorthand syntax | |
componentDidMount() { | |
fetch("./dinosaurs.json") | |
.then(res => res.json()) | |
.then(res => | |
this.setState({ | |
profiles: res | |
}) | |
) | |
} | |
// Refactors to -> | |
// 1. By renaming the arugment in the second `.then()`, we can pass it along directly to `this.setState()` | |
componentDidMount() { | |
fetch("./dinosaurs.json") | |
.then(res => res.json()) | |
.then(profiles => | |
this.setState({ | |
profiles | |
}) | |
) | |
} | |
// 2. We could also condense it more if we'd like | |
componentDidMount() { | |
fetch("./dinosaurs.json") | |
.then(res => res.json()) | |
.then(profiles => this.setState({ profiles })) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Challenge: Remove calls to `.querySelector()` | |
export class InputForm extends React.Component { | |
submitHandler(event) { | |
event.preventDefault() | |
const textareaValue = document.querySelector('#application-text').value | |
console.log(textareaValue) | |
} | |
render() { | |
return ( | |
<form id="application-input" onSubmit={this.submitHandler}> | |
<label>Apply Here: </label> | |
<textarea id="application-text" rows="8" cols="100" /> | |
<input id="submit" type="submit" value="Submit" /> | |
</form> | |
) | |
} | |
} | |
// Refactors to -> | |
// 1. Add `ref="appText"` to the textarea element. We can access refs on `this.refs.x` | |
// 2. Convert the `document.querySelector()` to be `this.refs.appText` instead, which will be equal to the DOM node | |
// 3. Since we are now using `this` inside our `submitHandler()` we need to bind the function with shorthand syntax | |
export class InputForm extends React.Component { | |
submitHandler = (event) => { | |
event.preventDefault() | |
const textareaValue = this.refs.appText.value | |
console.log(textareaValue) | |
} | |
render() { | |
return ( | |
<form id="application-input" onSubmit={this.submitHandler}> | |
<label>Apply Here: </label> | |
<textarea ref="appText" id="application-text" rows="8" cols="100" /> | |
<input id="submit" type="submit" value="Submit" /> | |
</form> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Challenge: Refactor for readability and testability | |
export class SkillList extends React.Component { | |
render() { | |
return ( | |
<ul className="skills-list"> | |
{this.props.dinosaurs.skills.map(item => <li key={item}>{item}</li>)} | |
</ul> | |
) | |
} | |
} | |
// Refactors to -> | |
// 1. We move the list item to it's own render method, naming it with `render...` to hint it's returning JSX | |
// This allows the `renderListItem()` method to be tested on it's own | |
// When your code becomes larger, this pattern will be easier to read | |
export class SkillList extends React.Component { | |
renderListItem(item) { | |
return <li key={item}>{item}</li> | |
} | |
render() { | |
return ( | |
<ul className="skills-list"> | |
{this.props.dinosaurs.skills.map(this.renderListItem)} | |
</ul> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great work Cheddar!!!