fix: Remove and update challenges with legacy methods (#36444)

This commit is contained in:
Oliver Eyton-Williams
2019-08-15 01:22:41 +01:00
committed by Jonathan Graham
parent 3e22e5febd
commit 44804abeb5
3 changed files with 2 additions and 161 deletions

View File

@ -151,10 +151,6 @@
"5a24c314108439a4d403617e", "5a24c314108439a4d403617e",
"Add Event Listeners" "Add Event Listeners"
], ],
[
"5a24c314108439a4d403617f",
"Manage Updates with Lifecycle Methods"
],
[ [
"5a24c314108439a4d4036180", "5a24c314108439a4d4036180",
"Optimize Re-Renders with shouldComponentUpdate" "Optimize Re-Renders with shouldComponentUpdate"
@ -210,4 +206,4 @@
], ],
"helpRoom": "Help", "helpRoom": "Help",
"fileName": "03-front-end-libraries/react.json" "fileName": "03-front-end-libraries/react.json"
} }

View File

@ -1,149 +0,0 @@
---
id: 5a24c314108439a4d403617f
title: Manage Updates with Lifecycle Methods
challengeType: 6
isRequired: false
forumTopicId: 301397
---
## Description
<section id='description'>
<strong>Warning:</strong>&nbsp;<code>componentWillReceiveProps()</code> and <code>componentWillUpdate()</code> are deprecated since their usage can lead to bugs and inconsistencies. They were replaced to, respectively, <code>UNSAFE_componentWillReceiveProps()</code> and <code>UNSAFE_componentWillUpdate()</code> and they should be avoided in new code.
Another lifecycle method is <code>UNSAFE_componentWillReceiveProps()</code> which is called whenever a component is receiving new props. This method receives the new props as an argument, which is usually written as <code>nextProps</code>. You can use this argument and compare with <code>this.props</code> and perform actions before the component updates. For example, you may call <code>setState()</code> locally before the update is processed.
Another method is <code>componentDidUpdate()</code>, and is called immediately after a component re-renders. Note that rendering and mounting are considered different things in the component lifecycle. When a page first loads, all components are mounted and this is where methods like <code>componentWillMount()</code> and <code>componentDidMount()</code> are called. After this, as state changes, components re-render themselves. The next challenge covers this in more detail.
</section>
## Instructions
<section id='instructions'>
The child component <code>Dialog</code> receives <code>message</code> props from its parent, the <code>Controller</code> component. Write the <code>UNSAFE_componentWillReceiveProps()</code> method in the <code>Dialog</code> component and have it log <code>this.props</code> and <code>nextProps</code> to the console. You'll need to pass <code>nextProps</code> as an argument to this method and although it's possible to name it anything, name it <code>nextProps</code> here.
Next, add <code>componentDidUpdate()</code> in the <code>Dialog</code> component, and log a statement that says the component has updated. This method works similar to <code>UNSAFE_componentWillUpdate()</code>, which is provided for you. Now click the button to change the message and watch your browser console. The order of the console statements show the order the methods are called.
<strong>Note:</strong>&nbsp;You'll need to write the lifecycle methods as normal functions and not as arrow functions to pass the tests (there is also no advantage to writing lifecycle methods as arrow functions).
</section>
## Tests
<section id='tests'>
```yml
tests:
- text: The <code>Controller</code> component should render the <code>Dialog</code> component as a child.
testString: assert((function() { const mockedComponent = Enzyme.mount(React.createElement(Controller)); return mockedComponent.find('Controller').length === 1 && mockedComponent.find('Dialog').length === 1; })(), 'The <code>Controller</code> component should render the <code>Dialog</code> component as a child.');
- text: The <code>UNSAFE_componentWillReceiveProps</code> method in the <code>Dialog</code> component should log <code>this.props</code> to the console.
testString: assert((function() { const lifecycleChild = React.createElement(Dialog).type.prototype.UNSAFE_componentWillReceiveProps.toString().replace(/ /g,''); return lifecycleChild.includes('console.log') && lifecycleChild.includes('this.props') })(), 'The <code>UNSAFE_componentWillReceiveProps</code> method in the <code>Dialog</code> component should log <code>this.props</code> to the console.');
- text: The <code>UNSAFE_componentWillReceiveProps</code> method in the <code>Dialog</code> component should log <code>nextProps</code> to the console.
testString: assert((function() { const lifecycleChild = React.createElement(Dialog).type.prototype.UNSAFE_componentWillReceiveProps.toString().replace(/ /g,''); const nextPropsAsParameterTest = /UNSAFE_componentWillReceiveProps(| *?= *?)(\(|)nextProps(\)|)( *?=> *?{| *?{|{)/; const nextPropsInConsoleLogTest = /console\.log\(.*?nextProps\b.*?\)/; return ( lifecycleChild.includes('console.log') && nextPropsInConsoleLogTest.test(lifecycleChild) && nextPropsAsParameterTest.test(lifecycleChild) ); })(), 'The <code>UNSAFE_componentWillReceiveProps</code> method in the <code>Dialog</code> component should log <code>nextProps</code> to the console.');
- text: The <code>Dialog</code> component should call the <code>componentDidUpdate</code> method and log a message to the console.
testString: assert((function() { const lifecycleChild = React.createElement(Dialog).type.prototype.componentDidUpdate.toString().replace(/ /g,''); return lifecycleChild.length !== 'undefined' && lifecycleChild.includes('console.log'); })());
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='jsx-seed'>
```jsx
class Dialog extends React.Component {
constructor(props) {
super(props);
}
UNSAFE_componentWillUpdate() {
console.log('Component is about to update...');
}
// change code below this line
// change code above this line
render() {
return <h1>{this.props.message}</h1>
}
};
class Controller extends React.Component {
constructor(props) {
super(props);
this.state = {
message: 'First Message'
};
this.changeMessage = this.changeMessage.bind(this);
}
changeMessage() {
this.setState({
message: 'Second Message'
});
}
render() {
return (
<div>
<button onClick={this.changeMessage}>Update</button>
<Dialog message={this.state.message}/>
</div>
);
}
};
```
</div>
### After Test
<div id='jsx-teardown'>
```js
ReactDOM.render(<Controller />, document.getElementById('root'))
```
</div>
</section>
## Solution
<section id='solution'>
```js
class Dialog extends React.Component {
constructor(props) {
super(props);
}
UNSAFE_componentWillUpdate() {
console.log('Component is about to update...');
}
// change code below this line
UNSAFE_componentWillReceiveProps(nextProps) {
console.log(this.props, nextProps);
}
componentDidUpdate() {
console.log('Component re-rendered');
}
// change code above this line
render() {
return <h1>{this.props.message}</h1>
}
};
class Controller extends React.Component {
constructor(props) {
super(props);
this.state = {
message: 'First Message'
};
this.changeMessage = this.changeMessage.bind(this);
}
changeMessage() {
this.setState({
message: 'Second Message'
});
}
render() {
return (
<div>
<button onClick={this.changeMessage}>Update</button>
<Dialog message={this.state.message}/>
</div>
);
}
};
```
</section>

View File

@ -14,7 +14,7 @@ This method is a useful way to optimize performance. For example, the default be
## Instructions ## Instructions
<section id='instructions'> <section id='instructions'>
The <code>shouldComponentUpdate()</code> method is added in a component called <code>OnlyEvens</code>. Currently, this method returns <code>true</code> so <code>OnlyEvens</code> re-renders every time it receives new <code>props</code>. Modify the method so <code>OnlyEvens</code> updates only if the <code>value</code> of its new props is even. Click the <code>Add</code> button and watch the order of events in your browser's console as the other lifecycle hooks are triggered. The <code>shouldComponentUpdate()</code> method is added in a component called <code>OnlyEvens</code>. Currently, this method returns <code>true</code> so <code>OnlyEvens</code> re-renders every time it receives new <code>props</code>. Modify the method so <code>OnlyEvens</code> updates only if the <code>value</code> of its new props is even. Click the <code>Add</code> button and watch the order of events in your browser's console as the lifecycle hooks are triggered.
</section> </section>
## Tests ## Tests
@ -51,9 +51,6 @@ class OnlyEvens extends React.Component {
return true; return true;
// change code above this line // change code above this line
} }
componentWillReceiveProps(nextProps) {
console.log('Receiving new props...');
}
componentDidUpdate() { componentDidUpdate() {
console.log('Component re-rendered.'); console.log('Component re-rendered.');
} }
@ -115,9 +112,6 @@ class OnlyEvens extends React.Component {
return nextProps.value % 2 === 0; return nextProps.value % 2 === 0;
// change code above this line // change code above this line
} }
componentWillReceiveProps(nextProps) {
console.log('Receiving new props...');
}
componentDidUpdate() { componentDidUpdate() {
console.log('Component re-rendered.'); console.log('Component re-rendered.');
} }