freeCodeCamp/curriculum/challenges/english/03-front-end-libraries/react/give-sibling-elements-a-uni...

4.5 KiB

id title challengeType isRequired
5a24c314108439a4d403618b Give Sibling Elements a Unique Key Attribute 6 false

Description

The last challenge showed how the map method is used to dynamically render a number of elements based on user input. However, there was an important piece missing from that example. When you create an array of elements, each one needs a key attribute set to a unique value. React uses these keys to keep track of which items are added, changed, or removed. This helps make the re-rendering process more efficient when the list is modified in any way.

Note: Keys only need to be unique between sibling elements, they don't need to be globally unique in your application.

Instructions

The code editor has an array with some front end frameworks and a stateless functional component named Frameworks(). Frameworks() needs to map the array to an unordered list, much like in the last challenge. Finish writing the map callback to return an li element for each framework in the frontEndFrameworks array. This time, make sure to give each li a key attribute, set to a unique value. The li elements should also contain text from frontEndFrameworks. Normally, you want to make the key something that uniquely identifies the element being rendered. As a last resort the array index may be used, but typically you should try to use a unique identification.

Tests

tests:
  - text: The <code>Frameworks</code> component should exist and render to the page.
    testString: assert(Enzyme.mount(React.createElement(Frameworks)).find('Frameworks').length === 1, 'The <code>Frameworks</code> component should exist and render to the page.');
  - text: <code>Frameworks</code> should render an <code>h1</code> element.
    testString: assert(Enzyme.mount(React.createElement(Frameworks)).find('h1').length === 1, '<code>Frameworks</code> should render an <code>h1</code> element.');
  - text: <code>Frameworks</code> should render a <code>ul</code> element.
    testString: assert(Enzyme.mount(React.createElement(Frameworks)).find('ul').length === 1, '<code>Frameworks</code> should render a <code>ul</code> element.');
  - text: The <code>ul</code> tag should render 6 child <code>li</code> elements.
    testString: assert(Enzyme.mount(React.createElement(Frameworks)).find('ul').children().length === 6 && Enzyme.mount(React.createElement(Frameworks)).find('ul').childAt(0).name() === 'li' && Enzyme.mount(React.createElement(Frameworks)).find('li').length === 6, 'The <code>ul</code> tag should render 6 child <code>li</code> elements.');
  - text: Each list item element should have a unique <code>key</code> attribute.
    testString: assert((() => { const ul = Enzyme.mount(React.createElement(Frameworks)).find('ul'); const keys = new Set([ ul.childAt(0).key(), ul.childAt(1).key(), ul.childAt(2).key(), ul.childAt(3).key(), ul.childAt(4).key(), ul.childAt(5).key(), ]); return keys.size === 6; })(), 'Each list item element should have a unique <code>key</code> attribute.');
  - text: Each list item element should contain text from <code>frontEndFrameworks</code>.
    testString: assert((() => {const li = Enzyme.mount(React.createElement(Frameworks)).find('ul').children(); return [...Array(5)].every((_, i) => frontEndFrameworks.includes(li.at(i).text()))})(), 'Each list item element should contain text from <code>frontEndFrameworks</code'); 

Challenge Seed


const frontEndFrameworks = [
  'React',
  'Angular',
  'Ember',
  'Knockout',
  'Backbone',
  'Vue'
];

function Frameworks() {
  const renderFrameworks = null; // change code here
  return (
    <div>
      <h1>Popular Front End JavaScript Frameworks</h1>
      <ul>
        {renderFrameworks}
      </ul>
    </div>
  );
};

After Test

ReactDOM.render(<Frameworks />, document.getElementById('root'))

Solution

const frontEndFrameworks = [
  'React',
  'Angular',
  'Ember',
  'Knockout',
  'Backbone',
  'Vue'
];

function Frameworks() {
  const renderFrameworks = frontEndFrameworks.map((fw, i) => <li key={i}>{fw}</li>);
  return (
    <div>
      <h1>Popular Front End JavaScript Frameworks</h1>
      <ul>
        {renderFrameworks}
      </ul>
    </div>
  );
};