'useEffect' 不止一次 运行
'useEffect' not run only once
谢谢大家,尤其是 Mr.Drew Reese。如果你和我一样是新手,请看他的.
我不知道为什么,但是当我控制台日志状态 data 如果我使用 useEffect,它总是重新渲染,尽管状态 generalInfo 没有改变:/所以有人可以帮我解决它并解释我的错误吗?
我想要 data 的结果将在 generalInfo 更改时更新。
非常感谢!
这是我的useEffect
======================== 这里有问题:
const {onGetGeneralInfo, generalInfo} = props;
const [data, setData] = useState(generalInfo);
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [generalInfo]);
========================修复:
useEffect(() => {
onGetGeneralInfo();
}, []);
useEffect(() => {
setData(generalInfo);
}, [generalInfo, setData]);
这是mapStateToProps
const mapStateToProps = state => {
const {general} = state;
return {
generalInfo: general.generalInfo,
};
};
这是 mapDispatchToProps
const mapDispatchToProps = dispatch => {
return {
onGetGeneralInfo: bindActionCreators(getGeneralInfo, dispatch),
};
};
这是减速机
case GET_GENERAL_INFO_SUCCESS: {
const {payload} = action;
return {
...state,
generalInfo: payload,
};
}
这是动作
export function getGeneralInfo(data) {
return {
type: GET_GENERAL_INFO,
payload: data,
};
}
export function getGeneralInfoSuccess(data) {
return {
type: GET_GENERAL_INFO_SUCCESS,
payload: data,
};
}
export function getGeneralInfoFail(data) {
return {
type: GET_GENERAL_INFO_FAIL,
payload: data,
};
}
这是 saga
export function* getGeneralInfoSaga() {
try {
const tokenKey = yield AsyncStorage.getItem('tokenKey');
const userId = yield AsyncStorage.getItem('userId');
const params = {
method: 'GET',
headers: {
Authorization: `Bearer ${tokenKey}`,
},
};
const response = yield call(
fetch,
`${API_GET_GENERAL_INFO}?id=${userId}`,
params,
);
const body = yield call([response, response.json]);
if (response.status === 200) {
yield put(getGeneralInfoSuccess(body));
} else {
yield put(getGeneralInfoFail());
throw new Error(response);
}
} catch (error) {
yield put(getGeneralInfoFail());
console.log(error);
}
}
在您的 useEfect
中您正在设置 generalInfo
,它会导致 useEffect
的依赖数组发生变化。所以,它一遍又一遍地运行:
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [generalInfo]);
试试这个:
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo); // or try to remove it if it is unnecessary based on below question.
}, []);
但是我不明白为什么你之前设置了useEffect
却用了setData(generalInfo);
。它在 onGetGeneralInfo();
函数中有变化吗?
Yow hook 拥有或使用了依赖项列表中未列出的东西
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [ onGetGeneralInfo, setData, generalInfo]);
还要记住 useEffect 是在组件挂载之前和挂载之后调用的,所以如果你添加一个日志,它会被打印出来
the initial state in redux and state in component is an empty array.
so I want to GET data from API. and I push it to redux's state. then I
useState it. I want to use useEffect because I want to update state
when I PUT the data and update local state after update.
好的,我了解到您希望在安装组件时获取数据,然后在填充时将获取的数据存储到本地状态。为此,您需要将关注点分离到单独的效果挂钩中。一个在组件挂载时分派一次数据获取,另一个“侦听”redux 状态的变化以更新本地状态。 请注意,通常认为将传递的 props 存储在本地状态中是反模式。
const {onGetGeneralInfo, generalInfo} = props;
const [data, setData] = useState(generalInfo);
// fetch data on mount
useEffect(() => {
onGetGeneralInfo();
}, []);
// Update local state when `generalInfo` updates.
useEffect(() => {
setData(generalInfo);
}, [generalInfo, setData]);
谢谢大家,尤其是 Mr.Drew Reese。如果你和我一样是新手,请看他的
我不知道为什么,但是当我控制台日志状态 data 如果我使用 useEffect,它总是重新渲染,尽管状态 generalInfo 没有改变:/所以有人可以帮我解决它并解释我的错误吗?
我想要 data 的结果将在 generalInfo 更改时更新。
非常感谢!
这是我的useEffect
======================== 这里有问题:
const {onGetGeneralInfo, generalInfo} = props;
const [data, setData] = useState(generalInfo);
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [generalInfo]);
========================修复:
useEffect(() => {
onGetGeneralInfo();
}, []);
useEffect(() => {
setData(generalInfo);
}, [generalInfo, setData]);
这是mapStateToProps
const mapStateToProps = state => {
const {general} = state;
return {
generalInfo: general.generalInfo,
};
};
这是 mapDispatchToProps
const mapDispatchToProps = dispatch => {
return {
onGetGeneralInfo: bindActionCreators(getGeneralInfo, dispatch),
};
};
这是减速机
case GET_GENERAL_INFO_SUCCESS: {
const {payload} = action;
return {
...state,
generalInfo: payload,
};
}
这是动作
export function getGeneralInfo(data) {
return {
type: GET_GENERAL_INFO,
payload: data,
};
}
export function getGeneralInfoSuccess(data) {
return {
type: GET_GENERAL_INFO_SUCCESS,
payload: data,
};
}
export function getGeneralInfoFail(data) {
return {
type: GET_GENERAL_INFO_FAIL,
payload: data,
};
}
这是 saga
export function* getGeneralInfoSaga() {
try {
const tokenKey = yield AsyncStorage.getItem('tokenKey');
const userId = yield AsyncStorage.getItem('userId');
const params = {
method: 'GET',
headers: {
Authorization: `Bearer ${tokenKey}`,
},
};
const response = yield call(
fetch,
`${API_GET_GENERAL_INFO}?id=${userId}`,
params,
);
const body = yield call([response, response.json]);
if (response.status === 200) {
yield put(getGeneralInfoSuccess(body));
} else {
yield put(getGeneralInfoFail());
throw new Error(response);
}
} catch (error) {
yield put(getGeneralInfoFail());
console.log(error);
}
}
在您的 useEfect
中您正在设置 generalInfo
,它会导致 useEffect
的依赖数组发生变化。所以,它一遍又一遍地运行:
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [generalInfo]);
试试这个:
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo); // or try to remove it if it is unnecessary based on below question.
}, []);
但是我不明白为什么你之前设置了useEffect
却用了setData(generalInfo);
。它在 onGetGeneralInfo();
函数中有变化吗?
Yow hook 拥有或使用了依赖项列表中未列出的东西
useEffect(() => {
onGetGeneralInfo();
setData(generalInfo);
}, [ onGetGeneralInfo, setData, generalInfo]);
还要记住 useEffect 是在组件挂载之前和挂载之后调用的,所以如果你添加一个日志,它会被打印出来
the initial state in redux and state in component is an empty array. so I want to GET data from API. and I push it to redux's state. then I useState it. I want to use useEffect because I want to update state when I PUT the data and update local state after update.
好的,我了解到您希望在安装组件时获取数据,然后在填充时将获取的数据存储到本地状态。为此,您需要将关注点分离到单独的效果挂钩中。一个在组件挂载时分派一次数据获取,另一个“侦听”redux 状态的变化以更新本地状态。 请注意,通常认为将传递的 props 存储在本地状态中是反模式。
const {onGetGeneralInfo, generalInfo} = props;
const [data, setData] = useState(generalInfo);
// fetch data on mount
useEffect(() => {
onGetGeneralInfo();
}, []);
// Update local state when `generalInfo` updates.
useEffect(() => {
setData(generalInfo);
}, [generalInfo, setData]);