fix some react warnings about non-unique keys

pull/118/head
Jon Eugster 3 years ago
parent 29b056cf05
commit 7568f1dd4a

@ -8,7 +8,7 @@ export function Hint({hint, step, selected, toggleSelection} : {hint: GameHint,
</div> </div>
} }
export function AdditionalHint({hint, step, selected, toggleSelection} : {hint: GameHint, step: number, selected: number, toggleSelection: any}) { export function HiddenHint({hint, step, selected, toggleSelection} : {hint: GameHint, step: number, selected: number, toggleSelection: any}) {
return <div className={`message warning step-${step}` + (step == selected ? ' selected' : '')} onClick={toggleSelection}> return <div className={`message warning step-${step}` + (step == selected ? ' selected' : '')} onClick={toggleSelection}>
<Markdown>{hint.text}</Markdown> <Markdown>{hint.text}</Markdown>
</div> </div>
@ -19,8 +19,9 @@ export function Hints({hints, showHidden, step, selected, toggleSelection} : {hi
const openHints = hints.filter(hint => !hint.hidden) const openHints = hints.filter(hint => !hint.hidden)
const hiddenHints = hints.filter(hint => hint.hidden) const hiddenHints = hints.filter(hint => hint.hidden)
// TODO: Should not use index as key.
return <> return <>
{openHints.map(hint => <Hint hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)} {openHints.map((hint, j) => <Hint key={`hint-${step}-${j}`} hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)}
{showHidden && hiddenHints.map(hint => <AdditionalHint hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)} {showHidden && hiddenHints.map((hint, j) => <HiddenHint key={`hidden-hint-${step}-${j}`} hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)}
</> </>
} }

@ -255,7 +255,8 @@ function GoalsTab({proofStep} : {proofStep: ProofStep}) {
return <div> return <div>
<div className="tab-bar"> <div className="tab-bar">
{proofStep.goals.map((goal, i) => ( {proofStep.goals.map((goal, i) => (
<div className={`tab ${i == (selectedGoal) ? "active": ""}`} onClick={(ev) => { setSelectedGoal(i); ev.stopPropagation() }}> // TODO: Should not use index as key.
<div key={`proof-goal-${i}`} className={`tab ${i == (selectedGoal) ? "active": ""}`} onClick={(ev) => { setSelectedGoal(i); ev.stopPropagation() }}>
{i ? `Goal ${i+1}` : "Active Goal"} {i ? `Goal ${i+1}` : "Active Goal"}
</div> </div>
))} ))}
@ -382,16 +383,15 @@ export function CommandLineInterface(props: {world: string, level: number, data:
if (i == proof.length - 1 && hasInteractiveErrors(step.errors)) { if (i == proof.length - 1 && hasInteractiveErrors(step.errors)) {
// if the last command contains an error, we only display the errors but not the // if the last command contains an error, we only display the errors but not the
// entered command as it is still present in the command line. // entered command as it is still present in the command line.
return <div> // TODO: Should not use index as key.
return <div key={`proof-step-${i}`}>
<Errors errors={step.errors} commandLineMode={true}/> <Errors errors={step.errors} commandLineMode={true}/>
</div> </div>
} else { } else {
return <> return <div key={`proof-step-${i}`} className={`step step-${i}` + (selectedStep == i ? ' selected' : '')} onClick={toggleSelectStep(i)}>
<div className={`step step-${i}` + (selectedStep == i ? ' selected' : '')} onClick={toggleSelectStep(i)}> <Command command={step.command} deleteProof={deleteProof(i)}/>
<Command command={step.command} deleteProof={deleteProof(i)}/> <Errors errors={step.errors} commandLineMode={true}/>
<Errors errors={step.errors} commandLineMode={true}/> <GoalsTab proofStep={step}/>
<GoalsTab proofStep={step}/>
</div>
{/* Show a message that there are no goals left */} {/* Show a message that there are no goals left */}
{!step.goals.length && ( {!step.goals.length && (
<div className="message information"> <div className="message information">
@ -404,7 +404,7 @@ export function CommandLineInterface(props: {world: string, level: number, data:
} }
</div> </div>
)} )}
</> </div>
} }
}) : <CircularProgress />} }) : <CircularProgress />}
</div> </div>

@ -48,10 +48,11 @@ function Error({error, commandLineMode} : {error : InteractiveDiagnostic, comman
</div> </div>
} }
// TODO: Should not use index as key.
/** A list of messages (info/warning/error) that are produced after this command */ /** A list of messages (info/warning/error) that are produced after this command */
export function Errors ({errors, commandLineMode} : {errors : InteractiveDiagnostic[], commandLineMode : boolean}) { export function Errors ({errors, commandLineMode} : {errors : InteractiveDiagnostic[], commandLineMode : boolean}) {
return <div> return <div>
{errors.map((err) => (<Error error={err} commandLineMode={commandLineMode}/>))} {errors.map((err, i) => (<Error key={`error-${i}`} error={err} commandLineMode={commandLineMode}/>))}
</div> </div>
} }

@ -60,20 +60,21 @@ function InventoryList({items, docType, openDoc, defaultTab=null, level=undefine
{categories.length > 1 && {categories.length > 1 &&
<div className="tab-bar"> <div className="tab-bar">
{categories.map((cat) => {categories.map((cat) =>
<div className={`tab ${cat == (tab ?? categories[0]) ? "active": ""}`} onClick={() => { setTab(cat) }}>{cat}</div>)} <div key={`category-${cat}`} className={`tab ${cat == (tab ?? categories[0]) ? "active": ""}`}
onClick={() => { setTab(cat) }}>{cat}</div>)}
</div>} </div>}
<div className="inventory-list"> <div className="inventory-list">
{ [...items].sort( {[...items].sort(
// For lemas, sort entries `available > disabled > locked` // For lemas, sort entries `available > disabled > locked`
// otherwise alphabetically // otherwise alphabetically
(x, y) => +(docType == "Lemma") * (+x.locked - +y.locked || +x.disabled - +y.disabled) (x, y) => +(docType == "Lemma") * (+x.locked - +y.locked || +x.disabled - +y.disabled)
).map(item => { ).filter(item => ((tab ?? categories[0]) == item.category)).map((item, i) => {
if ((tab ?? categories[0]) == item.category) { return <InventoryItem key={`${item.category}-${item.name}`}
return <InventoryItem key={item.name} showDoc={() => {openDoc(item.name, docType)}} showDoc={() => {openDoc(item.name, docType)}}
name={item.name} displayName={item.displayName} locked={item.locked} name={item.name} displayName={item.displayName} locked={item.locked}
disabled={item.disabled} newly={item.new}/> disabled={item.disabled} newly={item.new}/>
} })
}) } }
</div> </div>
</> </>
} }

@ -230,8 +230,10 @@ function PlayableLevel({worldId, levelId}) {
// It the last step has errors, it will have the same hints // It the last step has errors, it will have the same hints
// as the second-to-last step. Therefore we should not display them. // as the second-to-last step. Therefore we should not display them.
if (!(i == proof.length - 1 && hasInteractiveErrors(step.errors))) { if (!(i == proof.length - 1 && hasInteractiveErrors(step.errors))) {
return <Hints hints={step.hints} showHidden={showHiddenHints} step={i} // TODO: Should not use index as key.
selected={selectedStep} toggleSelection={toggleSelection(i)}/> return <Hints key={`hints-${i}`}
hints={step.hints} showHidden={showHiddenHints} step={i}
selected={selectedStep} toggleSelection={toggleSelection(i)}/>
} }
})} })}
{completed && {completed &&

Loading…
Cancel
Save