我想使用 UseSelector/userReducer 获取 3 个随机数据(彼此不同),但我无法访问数据

I want to get 3 random data (different from each other) using UseSelector/userReducer but I can't access the data

我想使用 useSelector 获取 3 个随机(但彼此不同)的用户数据,并将这些数据显示在 screen.but 上,它总是不必要地呈现,我无法达到我 wanted.Unfortunately 找不到哪里出错了

我的代码最终版本如下;

import * as React from "react";
import Avatar from "@mui/material/Avatar";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import { useSelector } from "react-redux";
import "./whoToFollow.css";

export default function WoToFollow() {
  const { authReducer, userReducer } = useSelector((state) => state);
  const authUser = authReducer?.user?.userId;
  const userList = userReducer?.data;

  var arrayMyUser = [];
  console.log("arrayMyUser =>>", arrayMyUser);
  var selected = [];
  // console.log("selected =>>", selected);

  function arrayUserList(callback) {
    setTimeout(function () {
      var arrayUsers = userList?.filter((user) => user?.userId !== authUser);
      arrayUsers?.map((item) => arrayMyUser.push(item));
    }, 1000);
    callback();
  }

  function rand() {
    setTimeout(function () {
      for (var i = 0; i < 3; i++) {
        var ran = arrayMyUser[Math.floor(Math.random() * arrayMyUser?.length)];
        console.log("ran =>> ", ran);
        if (selected.indexOf(ran) === -1) selected.push(ran);
      }
    }, 1000);
  }

  arrayUserList(rand);

  return (
    <Stack direction="row" spacing={2}>
      {selected &&
        selected?.map((p) => (
          <Box className="whotofollowavatar">
            <Avatar
              className="whotoFollowAvatar"
              alt={p?.name}
              src={p?.avatar}
            />
            <Typography variant="overline" display="block" gutterBottom>
              {p?.name + p?.surname}
            </Typography>
            <Button className="whotoFollowButton" variant="contained">
              Follow
            </Button>
          </Box>
        ))}
    </Stack>
  );
}

我尝试获取三个随机数据,但每次都出现不同的错误。我第一次得到“undefined”,然后我无法随机获取数据,有时我没有得到任何结果,因为数据来得晚..最后,数据有时如我所愿,有时却没有都来了

您可以试试这个,将函数封装在 useEffect 钩子中。我也觉得你最好有 arrayMyUser 的状态,并选择。这将是处理事物的“React”方式。

import * as React from "react";
import Avatar from "@mui/material/Avatar";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import { useSelector } from "react-redux";
import "./whoToFollow.css";

export default function WoToFollow() {
  const { authReducer, userReducer } = useSelector((state) => state);
  const authUser = authReducer?.user?.userId;
  const userList = userReducer?.data;

  var arrayMyUser = [];
  console.log("arrayMyUser =>>", arrayMyUser);
  var selected = [];
  // console.log("selected =>>", selected);

  function arrayUserList(callback) {
    setTimeout(function () {
      var arrayUsers = userList?.filter((user) => user?.userId !== authUser);
      arrayUsers?.map((item) => arrayMyUser.push(item));
    }, 1000);
    callback();
  }

  function rand() {
    setTimeout(function () {
      for (var i = 0; i < 3; i++) {
        var ran = arrayMyUser[Math.floor(Math.random() * arrayMyUser?.length)];
        console.log("ran =>> ", ran);
        if (selected.indexOf(ran) === -1) selected.push(ran);
      }
    }, 1000);
  }
  useEffect(() => {
    if (authUser && userList) {
      arrayUserList(rand);
    }
  }, [authUser, userList]);

  return (
    <Stack direction="row" spacing={2}>
      {selected &&
        selected?.map((p) => (
          <Box className="whotofollowavatar">
            <Avatar
              className="whotoFollowAvatar"
              alt={p?.name}
              src={p?.avatar}
            />
            <Typography variant="overline" display="block" gutterBottom>
              {p?.name + p?.surname}
            </Typography>
            <Button className="whotoFollowButton" variant="contained">
              Follow
            </Button>
          </Box>
        ))}
    </Stack>
  );
}

你遇到了一些问题,你做的每件事都非常复杂,使用 React 时要记住一些关键点:

  • 函数组件中除了钩子之外的每段代码都会在每次渲染时 运行,这意味着您定义的每个变量在每次渲染时都会有一个新值(钩子除外)
  • 如果需要在渲染之间存储值,请使用挂钩(useState 或 useRef 是最基本的)

这是你的组件,使用 useEffect + useState 来存储建议列表,(你的组件名称也有错别字):

function WhoToFollow() {
  const authUser = 3; // this is from your reducer
  const userList = useRef([...dummyUserList]); // this is from your reducer, ignore the useRef, is for testing
  const [suggestionList, setSuggestionList] = useState<any>([]); // replace any with the correct type

  useEffect(() => {
    if (authUser && userList) {
      setSuggestionList(() => {
        const { current: completeUserList } = userList;
        const filteredList = completeUserList.filter(
          (user) => user?.userId !== authUser
        );
        const newSuggestionList = [];

        while (newSuggestionList.length < 3) {
          const ran =
            filteredList[Math.floor(Math.random() * filteredList?.length)];
          if (newSuggestionList.indexOf(ran) === -1)
            newSuggestionList.push(ran);
        }

        return newSuggestionList;
      });
    }
  }, [userList, authUser]);

  return (
    <div>
      userList:
      {suggestionList.map((user: any) => (
        <div>{user.name}</div>
      ))}
    </div>
  );
}

我做了什么:

  • 将生成的列表存储在 useState 中
  • 将所有逻辑移至 useEffect 并删除函数,您不需要这些
  • 重构使用while生成3个建议的逻辑,用for不会每次都生成3个建议,如果发现重复的,不会添加新的

这是一个codesandbox:

https://codesandbox.io/s/kind-silence-3e5s80?file=/src/App.tsx