reactjs - 取数据后不断输入useEffect
问题描述
我useEffect
在Profile
组件中有这样的:
const [mappedPosts, setMappedPosts] = useState(null);
useEffect(() => {
fetchMedia();
if (userPosts) {
console.log("This keeps entering!");
const mapped = userPosts.map((post, index) => (
<View key={index}>
<Text>{post.title}</Text>
</View>
));
setMappedPosts(mapped);
}
}, []);
我的Profile
组件返回,
return mappedPosts ? (
<View>
{mappedPosts}
</View>
) : (
<Spinner />
);
我的问题如下:
当Spinner
我有组件时呈现:
useEffect(() => {
fetchMedia();
if (userPosts) {...};
setMappedPosts(mapped);
}
}, []);
或者
useEffect(() => {
fetchMedia();
if (userPosts) {...};
setMappedPosts(mapped);
}
}, [mappedPosts]);
当我有适当的数据时:
useEffect(() => {
fetchMedia();
if (userPosts) {...};
setMappedPosts(mapped);
}
}, [userPosts]);
或者
useEffect(() => {
fetchMedia();
if (userPosts) {...};
setMappedPosts(mapped);
}
});
最后两个的问题是,该行console.log("This keeps entering!");
反复打印,说明组件一直在重新渲染。我不确定我在这里做错了什么。以下变体也不断重新渲染组件:
const [mappedPosts, setMappedPosts] = useState(null);
useEffect(() => {
fetchMedia();
if (userPosts && mappedPosts === null) {
console.log("entered!");
const mapped = userPosts.map((post, index) => (
<View key={index}>
<Text>{post.title}</Text>
</View>
));
setMappedPosts(mapped);
}
}, [userPosts]);
console.log("am I being re-rendered?");
return mappedPosts ? (
<View>
{mappedPosts}
</View>
) : (
<Spinner />
);
我知道这一点是因为console.log("am I being re-rendered?");
不停地打印……即使数据已经在屏幕上正确渲染和显示(我正在使用 react-native)。
该Profile
组件userPosts
从 redux 存储中获取:
const Profile = ({
navigation,
posts: { userPosts, loading },
auth: { isAuthenticated },
fetchMedia,
checkAuth
}) => {
const [mappedPosts, setMappedPosts] = useState(null);
useEffect(() => {
fetchMedia();
.......
编辑:
fetchMedia
: _
export const fetchMedia = () => async dispatch => {
dispatch({
type: FETCH_MEDIA
});
try {
const response = await axios.get(`http://${GATEWAY}:5000/api/posts/user`);
dispatch({
type: MEDIA_SUCCESS,
payload: response.data
});
} catch (err) {
dispatch({
type: MEDIA_FAIL
});
}
};
减速机:
const initialState = {
userPosts: null,
loading: false
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case FETCH_MEDIA:
return {
...state,
loading: true
};
case MEDIA_SUCCESS:
return {
...state,
userPosts: payload,
loading: false
};
case MEDIA_FAIL:
return {
...state,
loading: false
};
default:
return state;
}
}
解决方案
您的答案可能会起作用,因为数据只会被获取一次并且userPost
永远不会更改参考。
通常将 REST 数据置于状态比您所做的要复杂一些。如果您需要数据,则容器将选择如下数据:
const NOT_REQUESTED = {requested:false}
state => state.data.someData || NOT_REQUESTED
然后组件可以请求数据,如果它没有被请求。
useEffect(()=>requested || fetchData(),[requested])
reducer 将设置请求和加载作为对请求操作的响应:
{
...state,
data: {
...state.data,
someData: { requested: true, loading: true },
},
};
现在,当您的组件将重新渲染但fetchData
由于请求为真而未被调用时。
当请求成功时,reducer 可以将结果写入数据成功操作:
{
...state,
data: {
...state.data,
someData: {
...state.data.someData,
loading: false,
data: action.data,
},
},
};
这与服务器端过滤、排序、陈旧数据或错误处理无关,但我希望你明白这一点。
如果您希望组件调度操作以加载数据,那么您的容器/选择器需要生成指示数据是否已被请求的道具。
推荐阅读
- bash - 无法在 sed 或 awk 中使用关联数组值
- neo4j - 查询联合取决于列表中的变量
- java - H2 内存表未在 Spring Boot 应用程序中填充
- mobile - 如果原生移动应用打开浏览器,它是否与原生浏览器共享本地存储?
- php - Google Analytics API - 返回的行数与返回的总数不同
- javascript - Phaser 3 阵列碰撞
- mysql - Mysql5.6 select语句重复id和set
- python - AttributeError:“NoneType”对象没有“读取”属性?
- python-3.9 - 将 Python 添加到 PATH
- javascript - 未捕获的 TypeError:data.reduce 不是函数