1

I have a textbox where a user enters text. A search for specific keywords is then performed and the string is split at these keywords.

A first input may look like E.g.

[
    0: "this is "
    1: "word"
    2: " a form field value with another "
    3: "word"
]

A change then might be made to remove the first repeated word:

[
    0: "this is "
    1: " a form field value with another "
    2: "word"
]

How can I create a persistent key for each array item? I need the second word value to have the same React key as when it is first generated regardless of array position. It is a separate component instance regardless of the same value. I have an issue right now where deleting one of the split words will delete both due to the keys changing after the first word is deleted.

Best practices say not to use the array index, but I'm unsure in this situation how else to generate a unique key.

4
  • 1
    In your case it seems like you can probably use Index only or combine index with word content like ${index}${value} Commented Mar 30, 2020 at 16:38
  • Use value as key. Commented Mar 30, 2020 at 16:39
  • Thanks @xdeepakv, but keys need to be unique. Same words would have same key. Commented Mar 30, 2020 at 17:04
  • Please check my answer! Commented Mar 30, 2020 at 17:11

4 Answers 4

2

This is a rough solution, but you can think of as a dictionary program.

class SomeComponent {
  constructor() {
    this.state = {
      words: ["this is ", "word", " a form field value with another ", "word"]
    };
    this.wordMap = this.state.words.reduce((m, x, index) => {
      m[index] = x;
      return m;
    }, {});
  }
  cleanWord() {
    let unique = new Set();
    for (let key in this.wordMap) {
      if (unique.has(this.wordMap[key])) {
        this.wordMap[key] = null; //duplicate
      } else {
        unique.add(this.wordMap[key]);
      }
    }
  }
  onDelete(index) {
    this.wordMap[index] = null;
  }
}
const dict = new SomeComponent();
dict.cleanWord();
console.log(dict.wordMap);

dict.onDelete(1);
console.log(dict.wordMap);
.as-console-row {color: blue!important}

Sign up to request clarification or add additional context in comments.

1 Comment

I ended up going with a solution like this.
0

You can use value as key, and keep the indexes as values

[
    "this is ": [0]
    "word": [1,3]
    " a form field value with another ":[2]
]

And then when you remove one index it will look like

[
    "this is ": [0]
    "word": [3]
    " a form field value with another ":[2]
]

You can use reduce to produce such format from your splitted string

let str = ["this is ", "word", " a form field value with another ", "word"]

let mapperObj = str.reduce((op, inp, index) => {
  op[inp] = op[inp] || []
  op[inp].push(index)
  return op
}, {})

console.log(mapperObj)

1 Comment

@RobFyffe these are, you can never have duplicate property name in object
0

You can use anything as the key, to the best of my knowledge, but you want them to be unique for each item.

I'd recommend base64'ing your item using btoa(JSON.stringify(object)) or creating a unique key like mentioned above by appending index to value, ${index}${value}

1 Comment

In React the keys must be unique. The same words would have the same key. Then removing the a value from the array would change the index so this means the key would not be persistent.
0

You can use index as key if you can mark deleted values as null. This value can be rendered without additional filtering.

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.