I got this code where I'm parsing dynamic text into separate lines and rendering individual components for each line of text.
I'm using the map
function to create an array for the elements and React demands a unique key for each element on the list.
I know usually it's not ideal to use index
as the key. But in this case, what else can I do?
QUESTION
Can I use index
as the key
for the elements in this case without having issues? What could go wrong?
Note1: I cannot use the values as the keys, because all lines might have the exact same values, hence they wouldn't be unique.
Note2: This code runs inside an Admin form for BlogPosts. I write some custom markup text, just like in the textarea for questions on StackOverflow and I need to parse it to give it proper styles when rendered out on the screen as a blog post. Like: **bold text**
, etc. And each line should be rendered as a different paragraph.
UPDATE:
I've read the article you all mentioned in comments and answer. And here's what the author points out:
Does my case meet all 3 requirements?
1 - Do they change? In theory they do.
2 - They have no ids.
3 - They are not filtered for sure. But are they reordered? What if you copy "line1\nline2\nline3"
paste into Notepad and change it to "line3\nline2\nline1"
and paste it back into the textarea
. Does it count as re-ordering? I just tested it and it renders just fine.
Anyway, so far I haven't run into any issues and it feels safe to use. But I would like an in-depth explanation of how it works in this case.
function App() {
const [inputValue,setInputValue] = React.useState("line1\nline2\nline3");
const lineItems = inputValue.split("\n").map((line,index) =>
<TextLine
key={index}
index={index}
value={line}
/>
);
return(
<React.Fragment>
<textarea
onChange={()=>setInputValue(event.target.value)}
value={inputValue}
style={{width: "300px", height: "60px"}}
/>
{lineItems}
</React.Fragment>
);
}
function TextLine(props) {
return(
<div>{props.value + " (key = " + props.index + ")"}</div>
);
}
ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>