gpt4 book ai didi

javascript - 与 Redux 的异步操作

转载 作者:行者123 更新时间:2023-11-30 00:05:41 25 4
gpt4 key购买 nike

我有一个连接到 Redux 存储的 React 组件。我在 componentWillMount 生命周期方法中获取资源(帖子)。

componentWillMount() {
this.props.fetchPosts();
}

该组件将订阅 Redux 商店并从商店获取 isFetchingposts

const mapStateToProps = (state) => {
return {
posts: getAllPosts(state),
isFetching: getIsFetchingPosts(state),
}
}

我想在它仍在获取时显示一个微调器,所以在 render 方法中我想这样做。

render() {
if (this.props.isFetching) {
return <Spinner />
}

return this.props.posts.map(post => <PostItem key={post.id}{...post}/>)
}

但是如果我在 render 方法中使用 console.log isFetching,它首先显示 false 然后显示 true然后最后 false

理想情况下,当此容器首次呈现时,isFetching 状态已设置为 true 并显示微调器。我需要做出哪些改变才能实现这一点?

这是 action creator 和 reducer 的代码

/*** Action Creator ***/
export const fetchPosts = () => (dispatch) => {
dispatch({
type: REQUEST_POSTS,
});

return axios({
method: 'get',
url: `${API_URL}/posts`,
})
.then(({data}) => {
dispatch({
type: RECEIVE_POSTS,
payload: data.posts,
})
})
.catch((response) => {
// some error handling.
});
}


/*** Reducers ***/
const initialState = {
isFetching: false,
allIds: [],
byId: {},
};

const isFetching = (state = initialState.isFetcthing, action) => {
switch (action.type) {
case REQUEST_POSTS:
return true;
case RECEIVE_POSTS:
return false;
default:
return state;
}
}

const allIds = (state = initialState.allIds, action) => {
switch (action.type) {
case RECEIVE_POSTS:
return action.payload.map(post => post.id);
default:
return state;
}
}

const byId = (state = initialState.byId, action) => {
switch (action.type) {
case RECEIVE_POSTS:
return action.payload.reduce((nextState, post) => {
nextState[post.id] = post;
return nextState;
}, {...state});
default:
return state;
}
}

const posts = combineReducers({
isFetching,
allIds,
byId,
});

export default posts;


/*** Selectors in 'posts.js' file ***/

export const getAllPosts = (state) => {
const { allId, byId } = state;
return allIds.map(id => byId[id]);
}

/*** rootReducer file ***/
import posts, * as fromPosts from './posts';


const rootReducer = combineReducers({
posts,
})

export default rootReducer;

export const getAllPosts = (state) => {
return fromPosts.getAllPosts(state.posts);
};

提前致谢!

最佳答案

简单的答案是,鉴于您的实现,这是预期的行为。您正在映射 isFetching声明 Prop 。这是正在发生的事情:

  1. isFetching的初始值在状态树中是 false , 所以 isFetching Prop 值为 false , 所以它呈现为 false .

  2. 您发送一个更改 isFetching 的操作至 true在状态树中。这个新状态映射到一个新的 isFetching true 的 Prop 值(value),这会导致重新渲染,渲染为 true .

  3. 您(异步地)派发另一个更改 isFetching 的操作返回false在状态树中。与 (2) 中相同,这会导致重新渲染,使用 isFetching作为false .

简单的解决方案,如果你只想渲染 true, false *,在当前的实现中,是设置 isFetchingtrue在你的 reducer 的初始状态。

这个实现在这个组件的设计层面上是否有意义是一个更广泛的问题,这里没有足够的上下文来回答:-)

*update 为了完整性我应该说我不知道​​ render()函数将被调用两次,使用 isFetching解析为 true,falsetrue,true,false 三遍在这种情况下。我怀疑 react-redux 可能会优化组件的渲染,这样如果映射 isFetching 就不会发生重新渲染。 Prop 从 true 更改-> true ,但不确定这一点 - 如果您能让我知道您的日志输出是什么,我们将不胜感激和感兴趣?

在任何情况下,由于标准的 react 虚拟 DOM 差异优化,在 DOM 级别肯定只会发生两次渲染,所以实际上结果是相同的两种方式

关于javascript - 与 Redux 的异步操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38640125/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com