我想使用react useEffect保存数组数据。以类为例:
async componentDidMount() {
const users = await AsyncStorage.getItem('users');
if (users) {
this.setState({ users: JSON.parse(users) });
}
}
componentDidUpdate(_, prevState) {
const { users } = this.state;
if (prevState.users !== users) {
AsyncStorage.setItem('users', JSON.stringify(users));
}
}
如何用React Hooks实现逻辑?
对于componentDidMount
逻辑,您可以使用useEffect
挂钩:
useEffect(() => {
const asyncFetch = async () => {
const users = await AsyncStorage.getItem("users");
if (users) {
// setter from useState
setUsers(JSON.parse(users));
}
};
asyncFetch();
}, []);
对于componentDidMount
,使用带dep阵列的useEffect
和useRef
参考。
const prevUsers = useRef();
useEffect(() => {
const prevUsers = prevUsers.current;
// Some equal check function
if (!areEqual(prevUsers, users)) {
AsyncStorage.setItem("users", JSON.stringify(users));
}
prevUsers.current = users;
}, [users]);
请注意,在您当前的代码中,
prevState.users !== users
总是truley,您比较两个对象,在JS中{} !== {}
总是得到true
。
您可以尝试如下,您可以在基于功能的组件中使用钩子,而不是在基于类的组件中使用钩子
//state declaration similar to class based component
const [usersdata,setUsers] = useState([]);
const users = await JSON.parse(AsyncStorage.getItem('users'));
//whenever the value of users changes useEffect will reset the value of users in state useEffect handle the lifecycle in function based component
useEffect(()=>{
if(users){
setUsers(JSON.parse(users));
}
},[users])
对于钩子,逻辑会发生轻微变化,您必须"钩子";你的效果是用一个状态来更新组件,所以当挂起的状态被更新时,组件会更新(componentDidUpdate
(,你显然可以挂起多个状态。
如果您选择不挂接任何状态,效果将仅在组件安装时执行,就像(componentDidMount()
(一样
我看不出让您决定何时更新用户状态的逻辑,因为您总是从存储中获取用户状态,所以我假设您有某种触发器,可以验证存储中的用户值是否发生了更改。
这样你就可以像这样重构你的代码:
const [users, setUsers] = useState([]);
const [userHasChanged, setUserHasChanged] = useState(false);
usEffect(async () => {
// comparing the old users with the new users is not useful since you always fetch the users from the storage, so the optimal is to always set the new array/ object to users, this way you avoid comparing the two objects which is a bit costly.
const newUsers = await AsyncStorage.getItem("users");
setUsers(JSON.parse(newUsers));
setUserHasChanged(false);
}, [userHasChanged])
// some code that triggers userHasChanged, you use setUserHasChaned(true)