我想知道在使用useEffect来获取数据后如何运行函数,而函数在提取数据后正在处理数据?
import React, { useState, useEffect } from 'react';
const Result = (props) => {
const [ playerName, setPlayerName ] = useState('');
const [ playerChoice, setPlayerChoice ] = useState(null);
const [ computerChoice, setComputerChoice ] = useState(null);
const [ result, setResult ] = useState(null);
useEffect(() => {
setPlayerName(props.location.state.playerName);
setPlayerChoice(props.location.state.playerChoice);
setComputerChoice(generateComputerChoice);
setResult(getResult())
}, []);
const getResult = () => {
// code that runs after the setting of the playerName and playerChoice. Will return "Win", "Lose", or "Draw"
};
const generateComputerChoice = () => {
const outcomes = [ 'Rock', 'Paper', 'Scissors' ];
return outcomes[Math.floor(Math.random() * outcomes.length)];
};
return (
<div className="app-container">
<strong>YOU {result}</strong>
<br />
<strong>{playerName}</strong> chose <strong>{playerChoice}</strong>
<br />
<strong>Computer</strong> chose <strong>{computerChoice}</strong>
</div>
);
};
export default Result;
因此,在此示例中,我从上一页抓取playerName
和playerChoice
,然后在页面加载时将其添加到useState中。
此后,我随机生成computerChoice
。
但是,在那之后,我想使用已经添加到状态中的playerChoice
和computerChoice
,并使用它来查看游戏是胜利,失败还是平局。
result
最终成为null
,因为我假设在调用getResult
函数时,状态尚未设置。
你们知道在这种情况下应该怎么做吗?考虑到您可能想从API中获取数据,然后在想要呈现它之前对这些数据执行某些操作,似乎这很常见。
答案 0 :(得分:0)
setState是异步的,您将只能在下一个渲染中使用该状态。与类组件不同,钩子在设置状态后不允许回调。
但是,查看组件并假设这就是组件的功能,就没有理由将playerName和playerChoice添加到组件的状态。您可以使用道具本身的数据。
SyntaxError
希望这会有所帮助。
答案 1 :(得分:0)
那第一个效果是不必要的。随便
const [playerName, setPlayerName] = useState(props.location.state.playerName);
答案 2 :(得分:0)
使用useMemo挂钩并将状态变量添加到其依赖项数组中。它将记录每个渲染周期的结果,因此仅在playerName
或playerChoice
更新时进行计算。
const getResult = useMemo(() => {
// code that runs after the setting of the playerName and playerChoice. Will return "Win", "Lose", or "Draw"
}, [playerName, playerChoice]);
糟糕,我现在看到您正在尝试将其保存到result
状态变量中,因此您可以使用具有相同依赖项的第二个useEffect代替我建议的useMemo,也可以在原始代码段中使用调用getResult()
函数的过程中,将签名更改为getResult(name, choice)
并使用当前渲染周期值(直接来自props)调用setResult。
useEffect(() => {
const { playerName, playerChoice } = props.location.state;
setPlayerName(playerName);
setPlayerChoice(playerChoice);
setComputerChoice(generateComputerChoice);
setResult(getResult(playerName, playerChoice));
}, []);
const getResult = (name, choice) => {
// Will return "Win", "Lose", or "Draw"
};
答案 3 :(得分:0)
谢谢大家的答复。最后,我重构为让计算机在上一个组件页面中生成选择,玩家也可以在其中进行选择。
这使得playerChoice和computerChoice都作为道具一起传递,这意味着可以使用数据而不必担心异步。
但是我对无论如何都可以解决此问题感兴趣。例如,如果我们从一个api调用,然后使用该api数据进行过滤(让我们按字母顺序或类似的方式对其进行排序),那么在useEffect api调用之后如何使用钩子来做到这一点?