我想使用 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
我想使用 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