从 useState 中的异步函数获取值
get value from async function in useState
我正在使用 async storage 检索我的数据,但我如何将它与 useState() 一起使用?
示例:
async function getdata(){
let d= await AsyncStorage.getItem('Name');
return d;
}
export default function App() {
const [name, setName] = useState(() => getdata());
return (<View>...</View>)
}
但这不起作用,因为 getdata() 是异步的,那么我该如何解决这个问题?
编辑:
我忘了说我试过这样的 useEffect() Hook:
async function getdata(){
let d= await AsyncStorage.getItem('Name');
console.log('retrieved Data!');
return d;
}
const [name, setName] = useState(()=>0);
useEffect(() => {
getData().then(setName);
console.log('moving on...');
}, []);
但执行顺序是:
'Moving on...'
'retrieved Data!'
相反的地方
您会将您的状态初始化为某个空值。可能是空字符串,也可能是 null。如果你愿意,你可以让你的组件在这段时间内渲染一些不同的东西,比如加载指示器。然后一旦数据加载,您可以设置状态以再次呈现。
export default function App() {
const [name, setName] = useState(null);
useEffect(() => {
getData().then(value => setName(value));
}, []);
if (name === null) {
return <Text>Loading...</Text>
} else {
return (<View>...</View>)
}
}
你必须使用useEffect
export default function App() {
const [name, setName] = useState('');
useEffect(() => {
const bootstrap = async () => {
const name = await getdata();
setName(name);
};
bootstrap();
}, []);
return <View>...</View>;
}
我认为这里最好的解决方案是将 name 初始化为 false,然后在 .then() 回调中使用 'setName'。 setName(以及那些通常来自 useState 的 setter 函数)是一种异步更新该值的方法。
我在这里将名称设置为布尔值 'false' 并严格检查。如果存在名称字段为空的情况,则可以将其设置为空字符串而不会导致无限循环。
async function getdata(){
let d= await AsyncStorage.getItem('Name');
return d;
}
export default function App() {
const [name, setName] = useState(false);
useEffect(() => {
if (name === false) {
getData().then((name) => {
setName(name);
});
}
}, []);
return (<View>...</View>)
}
请记住,您的视图必须能够处理虚假名称值。具体如何操作取决于您。
^^^上面的解决方案应该可以有效地解决你的问题,但我会在这里做一个简短的说明:如果你的组件相对复杂,它可能会因为其他原因重新渲染多次,因此 运行 if(name === false) 条件,因为它等待回调解决。这不会破坏任何东西,但它会比必要的更严重地影响异步存储,并可能影响性能。如果您发现是这种情况,请使用下面的有用文章查看 'debouncing' 回调。
https://medium.com/@gabrielmickey28/using-debounce-with-react-components-f988c28f52c1
我正在使用 async storage 检索我的数据,但我如何将它与 useState() 一起使用?
示例:
async function getdata(){
let d= await AsyncStorage.getItem('Name');
return d;
}
export default function App() {
const [name, setName] = useState(() => getdata());
return (<View>...</View>)
}
但这不起作用,因为 getdata() 是异步的,那么我该如何解决这个问题?
编辑:
我忘了说我试过这样的 useEffect() Hook:
async function getdata(){
let d= await AsyncStorage.getItem('Name');
console.log('retrieved Data!');
return d;
}
const [name, setName] = useState(()=>0);
useEffect(() => {
getData().then(setName);
console.log('moving on...');
}, []);
但执行顺序是:
'Moving on...'
'retrieved Data!'
相反的地方
您会将您的状态初始化为某个空值。可能是空字符串,也可能是 null。如果你愿意,你可以让你的组件在这段时间内渲染一些不同的东西,比如加载指示器。然后一旦数据加载,您可以设置状态以再次呈现。
export default function App() {
const [name, setName] = useState(null);
useEffect(() => {
getData().then(value => setName(value));
}, []);
if (name === null) {
return <Text>Loading...</Text>
} else {
return (<View>...</View>)
}
}
你必须使用useEffect
export default function App() {
const [name, setName] = useState('');
useEffect(() => {
const bootstrap = async () => {
const name = await getdata();
setName(name);
};
bootstrap();
}, []);
return <View>...</View>;
}
我认为这里最好的解决方案是将 name 初始化为 false,然后在 .then() 回调中使用 'setName'。 setName(以及那些通常来自 useState 的 setter 函数)是一种异步更新该值的方法。
我在这里将名称设置为布尔值 'false' 并严格检查。如果存在名称字段为空的情况,则可以将其设置为空字符串而不会导致无限循环。
async function getdata(){
let d= await AsyncStorage.getItem('Name');
return d;
}
export default function App() {
const [name, setName] = useState(false);
useEffect(() => {
if (name === false) {
getData().then((name) => {
setName(name);
});
}
}, []);
return (<View>...</View>)
}
请记住,您的视图必须能够处理虚假名称值。具体如何操作取决于您。
^^^上面的解决方案应该可以有效地解决你的问题,但我会在这里做一个简短的说明:如果你的组件相对复杂,它可能会因为其他原因重新渲染多次,因此 运行 if(name === false) 条件,因为它等待回调解决。这不会破坏任何东西,但它会比必要的更严重地影响异步存储,并可能影响性能。如果您发现是这种情况,请使用下面的有用文章查看 'debouncing' 回调。 https://medium.com/@gabrielmickey28/using-debounce-with-react-components-f988c28f52c1