steeleye / recruitment-ext

13 stars 25 forks source link

Vivanshu Gupta_Front End_12006965 #207

Open vivanshu-vvvg opened 1 year ago

vivanshu-vvvg commented 1 year ago

Q-1.) Explain what the simple List component does. Ans.) The provided code is a React component called "List" that displays a list of items with selectable options. It consists of two sub-components, "WrappedSingleListItem" and "WrappedListComponent". The "WrappedSingleListItem" component is a memoized functional component that represents a single item in the list. It takes four arguments: "index", "isSelected", "onClickHandler", and "text", and renders a list item element with a background color based on the selection status. The "WrappedListComponent" is also a memoized functional component that generates a list of items by utilizing the "WrappedSingleListItem" component. It takes an array of objects with "text" and "key" attributes as the "items" parameter. The component uses the "useState" and "useEffect" hooks to keep track of the index of the currently selected item. The List component iterates over an array of items and renders a SingleListItem component for each item. It passes relevant props to the SingleListItem component to handle the display and behavior of each item. The List component also manages the state of the selected index using the useState hook, which allows it to keep track of the currently selected item in the list. User clicks are handled through the handleClick function, which updates the selected index based on the user's actions. This way, the List component provides a dynamic and interactive list of selectable items for users to interact with on the website.

Q-2.) What problems / warnings are there with code? Ans.) Error 1: The error "Invalid prop 'isSelected' of type string supplied to WrappedSingleListItem, expected boolean" occurs because the propType of 'isSelected' has been set as boolean, but it is being assigned a value of string type, resulting in a type mismatch.

const handleClick = (index) => { console.log(index); handleItemSelect(index); setSelectedIndex === index ? selectedIndex(null) : selectedIndex(index); console.log(setSelectedIndex); };

Error 2: There was an error in declaring the selectedIndex variable. The error was related to the usage of useEffect hook, which complained about a missing dependency, specifically setSelectedIndex.

const [setSelectedIndex, selectedIndex] = useState();

Error 3: Since the map() method was called without proper data being passed from the App component, the selectedIndex variable was set to null by default, resulting in an error. To address this, a default prop for data can be set to ensure that the map() method has valid data to work with, even if it is not passed from the App component.

Error 4: There are issues with PropTypes usage in the code, specifically the incorrect use of "shapeOf" instead of "shape" to define the shape of an object prop. However, "arrayOf" is being used correctly to specify an array prop. It's crucial to rectify the usage of "shapeOf" to "shape" to ensure proper validation of PropTypes in the component.

WrappedListComponent.propTypes = { items: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string.isRequired }) ) };

Error 5: The function "onClickHandler" is being invoked as a regular function, causing the rendered color to always be green as it takes the initial value of the passed index. To correct this behavior, "onClickHandler" should be called as an arrow function to ensure it receives the updated value of the index.

onClick={()=>onClickHandler(index)} Error 6: When using React to map through an array and generate a list of elements, it's important to assign a unique key prop to each item. In the WrappedListComponent, make sure to add a key prop to the SingleListItem component to ensure proper rendering and performance optimization.

<SingleListItem key={index} //added text={item.text} //added index={index} isSelected={setSelectedIndex === index} //added currBtn={currBtn} //added selectedItems={selectedItems} //added onClickHandler={() => handleClick(index)} />

Q-3) Please fix, optimize, and/or modify the component as much as you think is necessary. Ans.) import React, { useState, memo } from "react"; import PropTypes from "prop-types"; import "./List.css"

const WrappedSingleListItem = ({ index, isSelected, text, currBtn, onClickHandler, selectedItems }) => { if (currBtn === 'single') { return ( <> <li style={{ backgroundColor: isSelected ? "green" : "red", letterSpacing: '0.8', border: '2px solid black', listStyleType: 'none', margin: '5px', height: '35px', textAlign: 'center', fontWeight: 700, cursor: 'pointer' }} onClick={() => onClickHandler(index)}

{text} </> ); } else if (currBtn === 'multiple') { return ( <> <li style={{ backgroundColor: selectedItems.includes(index) ? "green" : "red", letterSpacing: '0.8', border: '2px solid black', listStyleType: 'none', margin: '5px', height: '35px', textAlign: 'center', fontWeight: 700, cursor: 'pointer' }} onClick={() => onClickHandler(index)}

{text} </> ); } else { return ( <> <li style={{ backgroundColor: "red", letterSpacing: '0.8', border: '2px solid blue', margin: '5px', height: '35px', textAlign: 'center', listStyleType: 'none', fontWeight: 700, cursor: 'pointer' }} onClick={() => onClickHandler(index)}

{text} </> ); } };

WrappedSingleListItem.propTypes = { index: PropTypes.number, isSelected: PropTypes.bool, onClickHandler: PropTypes.func.isRequired, selectedItems:PropTypes.array, text: PropTypes.string.isRequired };

const SingleListItem = memo(WrappedSingleListItem);

const WrappedListComponent = ({ items }, props) => { const [setSelectedIndex, selectedIndex] = useState();

const [currBtn, setcurrBtn] = useState('single');

const onClickSingle = () => {
    setcurrBtn('single');
    console.log("single");

}
const onClickMultiple = () => { 
    setcurrBtn('multiple');
    console.log("multiple");
}
const onClickClear = () => { 
    setcurrBtn('clear');
    setSelectedItems([]);
    selectedIndex(null);
    console.log(props);
}

const [selectedItems, setSelectedItems] = useState([]);
const handleItemSelect = (itemId) => {
    if (selectedItems.includes(itemId) && currBtn==='multiple') {
        setSelectedItems(selectedItems.filter(id => id !== itemId));
    } else if(currBtn==='multiple'){
        setSelectedItems([...selectedItems, itemId]);
    }
}

const handleClick = (index) => {
    console.log(index);
    handleItemSelect(index);
    setSelectedIndex === index ? selectedIndex(null) : selectedIndex(index);
    console.log(setSelectedIndex);
};

return (
    <>
    <ul style={{ textAlign: "left", marginTop: '40px',paddingRight:'35px'}}>
        {items.map((item, index) => (
            <SingleListItem
                key={index}        
                text={item.text}    
                index={index}
                isSelected={setSelectedIndex === index}   
                currBtn={currBtn}              
                selectedItems={selectedItems}       
                onClickHandler={() => handleClick(index)}
            />
        ))}
    </ul>
    <div className="container" style={{
        margin: 'auto',
        width: '20%',
        marginRight: '100px',
        padding: '50px',
        display: 'flex',
        justifyContent: 'space-between'
    }}>

<button type="button" onClick={onClickSingle} style={currBtn==='single'?{border:'6px solid black'}:{border:'none'}} class="btn btn-success mx-2">Single <button type="button" onClick={onClickMultiple} style={currBtn==='multiple'?{border:'6px solid black'}:{border:'none'}} class="btn btn-danger mx-2">Multiple <button type="button" onClick={onClickClear} style={currBtn==='clear'?{border:'6px solid black'}:{border:'none'}} class="btn btn-warning mx-2">Clear

</> ); };

WrappedListComponent.propTypes = { items: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string.isRequired }) ) };

WrappedListComponent.defaultProps = { items: [ { text: "Taj Mahal", }, { text: "Red Fort", }, { text: "Gateway Of India", }, { text: "Dadra and Nagar Haveli", }, { text: "Qutub Minar", }, { text: "Ajanta and Elora caves", }, { text: "India Gate", }, ] };

const List = memo(WrappedListComponent);

export default List;