2

I'm using https://github.com/signavio/react-mentions for React Mentions, a facebook @mentions-like frontend feature where a user can mention another user in the comment box.

Below is the code that gets data through fetch but couldn't get the data using redux and useSelector.

I used react-mentions and react-redux packages

Using fetchUsers query I can get the data from github and pass them to Mention component for '@' suggestions.

Now how to use redux instead of fetch to display suggestions for '#'? i.e, how to use callback passed to the getData function to get the hashtag suggestions?

import { useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';

import { MentionsInput, Mention } from 'react-mentions';

import {
  fetchHashTags,
} from './redux/tagsSlice';

function fetchUsers(query, callback) {
  if (!query) return
  fetch(`https://api.github.com/search/users?q=${query}`, { json: true })
    .then(res => res.json())

    // Transform the users to what react-mentions expects
    .then(res =>
      res.items.map(user => ({ display: user.login, id: user.login }))
    )
    .then(callback)
}

function AsyncGithubUserMentions({ value, data, onChange }) {
  const dispatch = useDispatch();

  const users = useSelector(
    (state) => state?.tags?.users,
    shallowEqual
  );

  const getData = (query, callback) => {
    dispatch(fetchHashTags(query));
    callback(users);
  }

  return (
    <div className="async">
      <h3>Async Github user mentions</h3>

      <MentionsInput
        value={value}
        onChange={onChange}
        placeholder="Mention any Github user by typing `@` followed by at least one char"
        a11ySuggestionsListLabel={"Suggested Github users for mention"}
      >
        <Mention
          displayTransform={login => `@${login}`}
          trigger="@"
          data={fetchUsers}
        />
        <Mention
          displayTransform={login => `@${login}`}
          trigger="#"
          data={getData}
        />
      </MentionsInput>
    </div>
  )
}

export default AsyncGithubUserMentions

Redux code to fetch the hashtags from github:

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';

export const fetchHashTags = createAsyncThunk(
  'tags/hash',
  async (value, { rejectWithValue, getState, dispatch }) => {
    try {
      const { data } = await axios.get(
        `https://api.github.com/search/users?q=${query}`,
      );

      return data;
    } catch (error) {
      throw error;
    }
  }
);

const tagsSlice = createSlice({
  name: 'tags',
  initialState: {},
  extraReducers: (builder) => {
    builder.addCase(fetchHashTags.fulfilled, (state, action) => {
      state.usertags = action?.payload;
    });
  },
});

export default tagsSlice.reducer;

Ramesh Kumar
  • 147
  • 14

1 Answers1

0

The react-mentions docs do a bad job of showing how to do async calls. This construct worked for me, through trial and error.

function fetchUsers(query, callback) {
  if (!query) return;
  fetch(`https://api.github.com/search/users?q=${query}`, { json: true })
    .then((res) => res.json())
    .then((res) => callback(res.items.map((user) => ({ display: user.login, id: user.login }))));
}
russjman
  • 486
  • 9
  • 19