Search code examples
react-nativemention

reactnative controlled-mentions can not replace multi mentions inside string


i am using https://github.com/dabakovich/react-native-controlled-mentions to handle mentions inside my chat app, as documents, this is working:

import { replaceMentionValues } from 'react-native-controlled-mentions';

const value = 'Hello @[David Tabaka](5)! How are you?';

console.log(replaceMentionValues(value, ({id}) => `@${id}`)); // Hello @5! How are you?
console.log(replaceMentionValues(value, ({name}) => `@${name}`)); // Hello @David Tabaka! How are you?

But when i have multi mentions like this:

@[demo5](d3f0c3cd-f363-4303-8761-8e190f054be3) @[demo8](8dbafd40-b86f-490a-828d-d11dfe221b43) test

the function not working as expected, always convert first mention only

replaceMentionValues(text, ({name}) =>  `@${name}`)

=> @demo5 @[demo8](8dbafd40-b86f-490a-828d-d11dfe221b43) test

Can someone help my problem


Solution

  • You have found a bug in the library, but notice that this is a pre-release.

    Here is my test code:

    import * as React from 'react';
    import { replaceMentionValues } from 'react-native-controlled-mentions';
    
    const App = () => {
    
      const test = '@[demo5](d3f0c3cd-f363-4303-8761-8e190f054be3) @[demo8](8dbafd40-b86f-490a-828d-d11dfe221b43) test';
    
      console.log(replaceMentionValues(test, ({name}) =>  `@${name}`))
    
      return (
        <></>
      );
    };
    export default App;
    

    I have tested the version 3.0.0-alpha.1 which you can test in this snack and it works as we expect it to work.

    However, here is the same test using version 3.0.0-alpha.2 and it does not work.

    There is already a reported bug on Github.

    Edit: This seems to be fixed in the newest version of the 3.0 branch. The function replaceMentionValues is renamed to replaceTriggerValues and the matched strings have changed a little bit, though. There is a valid test case located in utils.test.ts in the last test case. You can see the new pattern here.

    The cause of this issue was located in constraints.ts in 3.0.0-alpha.2 which defines the following regex: const mentionRegEx = /((.)\[([^[]*)]\(([^(^)]*)\))/i;. In 3.0.0-alpha.1 the used regex is located in utils.ts and is as follows: const mentionRegEx = /((.)\[([^[]*)]\(([^(^)]*)\))/gi;. The delimiter is not global anymore, thus not all words will be matched.

    The new function replaceTriggerValues adds the missing g.

    Thus, either downgrade to 3.0.0-alpha.1 or use the newest version of the 3.0 branch. I have added a comment to the Github issue as well.