0

I am learning ReactJS from a last few days and I encountered a specific problem of rendering elements via loop. Please throw some light on the problem

This script works fine when we are calling the removeItem function from PostList block provided
In PostList function block we have

<Post key = {index} ..... removeItem = {() => props.removeItem(index)}/>

and in Post function block we have

<PostButton label = "x" handleClick = {props.removeItem}/>

But if I pass this removeItem function to the Post block and call the function like

In PostList function block we have

<Post key = {index} ..... removeItem = {props.removeItem}/> 

and
in Post function block we have

<PostButton label = "x" handleClick = {() => props.removeItem(props.key)}/>    

Wrong Implemented Code Then there occurs some bug the removal of item and it is not proper the item whose remove button get clicked isn't being removed but the one who is its former get removed. I assume the cause is that the removal of element from postList variable affects the indexing in the second case but handled properly in first case by re-rendering the postList again. Can someone please through some light on how indexing works while processing elements while rendering them through a loop in React

function PostButton(props){
    var style = {
        width:24,
        height:24
    }
    return (
        <button style = {style} onClick = { () => props.handleClick()}>{props.label}</button>
    )
}
function PostText(props){
    var style = {
        border:"1px solid black",
        width: props.width
    }
    return (
        <div style = {style}>{props.text}</div>
    )
}
function Post(props){
    var style = {
        display:"flex"
    }
    return (
        <div style = {style}>
            <PostButton label = "x" handleClick = {props.removeItem}/>
            <PostText text = {props.title} width = "200"/>
            <PostButton label = "+" handleClick = {props.incrementScore}/>
            <PostText text = {props.score} width = "20"/>
            <PostButton label = "-" handleClick = {props.decrementScore}/>
        </div>
    )
}

function PostList(props){
    return (
        <ol>
        {
            props.postList.map((item,index) => 
                <Post key = {index} 
                      title = {item.title} 
                      score = {item.score}
                      incrementScore = {() => props.updateScore(index,1)}                         
                      decrementScore = {() => props.updateScore(index,-1)} 
                      removeItem = {() => props.removeItem(index)}
                />
             )
         }
        </ol>
    )  
}
class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {value:"", items : []}
    } 
    handleChange(event){
        this.setState({value:event.target.value})
    }
    addItem(){

        var itemsCopy = this.state.items.slice()
        var truncatedString = this.state.value.substring(0,20);
        itemsCopy.push({"title":truncatedString,"score":0})
        itemsCopy.sort((a,b)=>{
          return b.score - a.score;
        })
        this.setState({items:itemsCopy,value:""})
    }
    removeItem(index){
        var itemsCopy = this.state.items.slice()
        itemsCopy.splice(index,1);
        itemsCopy.sort((a,b) => {
            return b.score - a.score
        })

        this.setState({items:itemsCopy})
    }
    updateScore(index,val){
        var itemsCopy = this.state.items.slice()
        itemsCopy[index].score += val
        itemsCopy.sort((a,b) => {
            return b.score - a.score
        })
        this.setState({items:itemsCopy})
    }
    render(){
        return (
            <div>
                <input value = {this.state.value} onChange = {this.handleChange.bind(this)}/>
                <button onClick = { () => this.addItem()}>Submit</button>
                <PostList postList = {this.state.items}
                          updateScore = {this.updateScore.bind(this)}  
                          removeItem = {this.removeItem.bind(this)}
                />

            </div>
        )
    }
}

ReactDOM.render(
    <App/>,
    document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="root"></div>

1 Answer 1

2

Key is not a prop in React. A key is a special attribute wich help React identify which items have changed, are added, or are removed. docs

If you want to use this index in PostButton component, you should pass it separatly:

<Post key = {index} ..... id={index} removeItem = {() => props.removeItem(index)}/>

<PostButton label = "x" handleClick = {() => props.removeItem(props.id)}/> 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.