Git Product home page Git Product logo

react-dynamic-components-lab's Introduction

React Dynamic Components Lab

Learning Goals

  • Practice writing dynamic components
  • Practice jumping into existing code and making the necessary changes

Introduction

In this lab, you'll write React components and render them dynamically based on information they receive from their parent components. This will enable us to use components as templates with the ability to render variable content.

There are two discrete parts of this lab, and they should be tackled one after the other. We will need to first create a Comment component from scratch and then add a few things to the ColorBox component.

All of the css has been provided, as well as a good amount of starter code. The general structure has already been provided - you are to pick up where the code leaves off and make both the Comment and the ColorBox components behave dynamically.

Here is an image of what we want once we are finished, complete with a view of the rendered DOM tree on the right:

completed example

...and here is a tree view of our component parent-child structure:

└── App
    ├── BlogPost
    │   ├── Comment
    │   ├── Comment
    │   └── Comment
    │
    └── ColorBox
        └── ColorBox
            └── ColorBox
                └── ColorBox (etc.)

Go ahead and npm start to see what we already have rendering in the browser.

Deliverables

(The application will error on npm start until the Comment component is created and exported)

Comment Component

  • Create a Comment component in the file, Comment.js within src/ and don't forget to:
    • import React, { Component } from 'react' at the top of our file
    • Use the class X extends Component {} syntax
    • export the class so it can be used in other files
    • import the class in BlogPost
  • It should expect a single prop (the text of a comment), which can be used in the component via: this.props.commentText. This prop is passed in src/BlogPost.js
  • It should have a single <div> in its render() method
  • The <div> should have a className="comment" attribute
  • Note: The BlogPost component needs minor alteration to properly pass the contents of its commentsArray to each of the Comment components that it is rendering
  • Don't forget - we can unpack variable values directly with JSX by wrapping them in {}, i.e. {this.props.commentText}

Take a Break

  • Look at something other than your computer screen for at least five minutes

ColorBox Component

  • Should expect a single prop (an opacity value), which can be used in the component via: this.props.opacity. This prop is first passed in src/App.js
  • If the opacity value is greater than or equal to 0.2:
    • the ColorBox component should render another ColorBox inside itself (recursive components!)
    • an opacity prop should be passed to the child
    • the passed opacity prop should be reduced by 0.1
  • If the opacity value is less than 0.2:
    • do not render another ColorBox (or else we would have infinite ColorBoxes rendering!)
    • instead, the render method should return null

Hints on ColorBox

  • While the idea of recursive components may seem complicated at first, we know that React components can have child components rendered inside them. That's exactly what's happening here. The only difference is that the child component happens to be the same as the component that rendered it. There's no reason you can't do that in React, however...
  • Watch out for endless recursion! If your ColorBox component has no break condition to stop it from always rendering another ColorBox, your browser will likely become non-responsive. Pre-plan how you are going to render the ColorBox before trying to code it.
  • You may find that subtracting 0.1 from your opacity prop is leading to some strange precision errors (try logging the opacity prop with each render). This is due to limitations with JavaScript float (number) types.
  • In order to render based on a conditional, you can write JavaScript logic directly in the render() block. In the example below, the render() method is returning the evaluation of a ternary operator. If the expression this.props.value > 100 evaluates to be true, the entire ternary expression (and thus, the return value of render()) evaluates to be null, otherwise, render() will return some JSX.
import React, { Component } from "react";

export default class Example extends Component {
  render() {
    const newValue = this.props.value * 2;
    return this.props.value > 100 ? null : (
      <div>
        <Example value={newValue} />
      </div>
    );
  }
}

Resources

react-dynamic-components-lab's People

Contributors

danielseehausen avatar dependabot[bot] avatar ihollander avatar kkterai avatar lizbur10 avatar maxwellbenton avatar rrcobb avatar sylwiavargas avatar thuyanduong-flatiron avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-dynamic-components-lab's Issues

type error

Under Comment component, it has to be "Create a Comment component instead of Component component. Simple mistyping :)

Typo

There is a typo I believe at the end of the third paragraph of the Introduction section.

All of the css has been provided, as well as a good amount of starter code. The general structure has already been provided - you are to pick up where the code leaves off and make both the Comment and the ColorBox components behave dynamically**.f**

Unable to run npm test

`// ♥ npm test

[email protected] test
mocha --timeout 5000 -w test/helpers.js test/*.js

Warning: Could not find any test files matching pattern: test/helpers.js

This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills
This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills
ReferenceError: React is not defined
at Object. (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/src/Comment.js:1:23)
at Module._compile (node:internal/modules/cjs/loader:1083:30)
at loader (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions. [as .js] (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/babel-register/lib/node.js:154:7)
at Module.load (node:internal/modules/cjs/loader:948:32)
at Function.Module._load (node:internal/modules/cjs/loader:789:14)
at Module.require (node:internal/modules/cjs/loader:972:19)
at require (node:internal/modules/cjs/helpers:88:18)
at Object. (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/test/index-test.js:10:1)
at Module._compile (node:internal/modules/cjs/loader:1083:30)
at loader (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions. [as .js] (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/babel-register/lib/node.js:154:7)
at Module.load (node:internal/modules/cjs/loader:948:32)
at Function.Module._load (node:internal/modules/cjs/loader:789:14)
at Module.require (node:internal/modules/cjs/loader:972:19)
at require (node:internal/modules/cjs/helpers:88:18)
at /home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/mocha/lib/mocha.js:250:27
at Array.forEach ()
at Mocha.loadFiles (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/mocha/lib/mocha.js:247:14)
at Mocha.run (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/mocha/lib/mocha.js:576:10)
at loadAndRun (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/mocha/bin/_mocha:594:22)
at Object. (/home/igor/dev/flatiron/labs/react-dynamic-components-lab/node_modules/mocha/bin/_mocha:611:3)
at Module._compile (node:internal/modules/cjs/loader:1083:30)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1112:10)
at Module.load (node:internal/modules/cjs/loader:948:32)
at Function.Module._load (node:internal/modules/cjs/loader:789:14)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:72:12)
at node:internal/main/run_main_module:17:47
(node:1741) DeprecationWarning: "--compilers" will be removed in a future version of Mocha; see https://git.io/vdcSr for more info
(Use node --trace-deprecation ... to show where the warning was created)`

incorrect colorbox instructions

ColorBox instructions say:
if the opacity value is greater than or equal to 0.1:

but tests won't pass unless value used is >= 0.2, this value is also used in the solution

Setting default browser error

For future students - if you meet an error upon running npm start along the lines of "would you like to set a default browser...", take a look at the top of this Readme.

Adding the below to package.json will enable you to bypass this message, start up a server, and actually proceed with the lab.
"browserslist": [ "defaults", "not IE 11", "not IE_Mob 11", "maintained node versions" ]

IDE error

[10:18:16] (master) react-dynamic-components-lab-online-web-sp-000
// ♥ Traceback (most recent call last):
11: from /usr/local/rvm/gems/ruby-2.6.1/bin/ruby_executable_hooks:24:in <main>' 10: from /usr/local/rvm/gems/ruby-2.6.1/bin/ruby_executable_hooks:24:in eval'
9: from /usr/local/rvm/gems/ruby-2.6.1/bin/learn-test:23:in <main>' 8: from /usr/local/rvm/gems/ruby-2.6.1/bin/learn-test:23:in load'
7: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/bin/learn-test:68:in <top (required)>' 6: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/runner.rb:20:in run'
5: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/runner.rb:20:in fork' 4: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/runner.rb:21:in block in run'
3: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/runner.rb:44:in report_and_clean' 2: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/reporter.rb:13:in report'
1: from /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/reporter.rb:47:in report' /usr/local/rvm/gems/ruby-2.6.1/gems/learn-test-2.6.1/lib/learn_test/strategies/mocha.rb:42:in results': undefined method `[]' for nil:NilClass
(NoMethodError)

Model Code Does Not Work

Using the model code, I could not get the ColorBox to render.

Given code:

    render() {
        const newValue = this.props.value * 2;
 
        if (this.props.value < 100) {
            return (
                <div>
                    <Example value={newValue} />
                </div>
            );
        } else {
            return null;
        }
    }
}```

My ColorBox code:
```import React, { Component } from 'react';

export default class ColorBox extends Component {
  
  render() {    
    const newValue = this.props.opacity - 0.1;

    if (this.props.opacity >= 0.2) {
      return (
        <div>
          <ColorBox opacity={newValue} />
        </div>
      );
    } else {
      return null;
    }
  }
}```

Additionally, the solution code uses a different approach.

Issue with learn test

Students were having some issues with learn test. TCs were able to resolve the issue and get tests running without issue by doing the following tasks:
add "whatwg-url": "8.0.0" to the dependencies in package.json
delete package-lock.json file & node-modules folder
run npm install again

"run local tests" not showing as completed

all tests passing & lesson submitted, but "run local tests" not showing as completed. not giving option for "next lesson" (have to navigate via course dropdown menu) and not showing completed in course dropdown menu

Note to add conditional code in the wrong spot.

This is minor, but just a bit misleading. In the provided code, the comment in the ColorBox component that says where to put your conditional statement is inside the return statement. It's also inside the div, which is again misleading because in the provided code the opacity value is explicitly stated, when it should really be a prop. To successfully have any conditional statement, it should be outside of the return, and offer a return option for each outcome.

Current starting code:
render() { return ( <div className="color-box" style={{opacity: 2}}> {/* your conditional code here! */} </div> ) }

Less misleading starting code:
render() { if ( {/* your conditional statement here! */} ) { return ( <div className="color-box" style={{ /* reference to opacity */ }}> {/* code to run if conditional is met */} </div> ) } else { return ( {/* code to run if it is not met */} ) } }

Or idk, maybe it doesn't need to be so explicit as to lay out the if statement entirely. It is (almost) a regular JS if statement with conditional returns, which was covered in the last unit. But since there are some differences between JSX and vanilla JS, putting a comment to specifically add the conditional inside both the return and the div is confusing because it could appear to be one of those differences to someone that is new to React.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.