reactjs - MapDispatchToProps 返回一个函数
问题描述
我尝试从我的 firebase 数据库中阅读我的文章,但我无法让它工作。
这是我的数据库:
myDB-myid
articles
1
body: "Lorem Ipsum Dolor si damet blablabla"
createdAt: 12345
subtitle: "ça promet beaucoup d'autres supers articles"
title: "Mon premier article"
2
body: "Encore du Lorem Ipsum et bla et bla et bla..."
createdAt: 34567
subtitle: "Vous avez aimé le premier ? Le deuxième va vous..."
title: "Et voici le deuxième article"
我的组件应该呈现所有文章的列表,ArticlePage
:
import React from 'react';
import { connect } from 'react-redux';
import Article from './Article';
import { startSetArticles } from '../../actions/articles';
const ArticlesPage = props => (
<div className="articles-wrapper">
<div className="container">
{console.log(props.articles)}
{
props.articles.length === 0 ? (
<p>No article</p>
) : (
props.articles.map(a => {
return <Article key={a.id} {...a}/>
})
)
}
</div>
</div>
);
const mapDispatchToProps = dispatch => ({
articles: () => dispatch(startSetArticles())
});
export default connect(undefined, mapDispatchToProps)(ArticlesPage);
我的商店:
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import authReducer from '../reducers/auth';
import articlesReducer from '../reducers/articles';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export default () => {
const store = createStore(
combineReducers({
auth: authReducer,
articles: articlesReducer
}),
composeEnhancers(applyMiddleware(thunk))
);
return store;
};
我的行动action/articles.js
:
import database from '../firebase/firebase';
// SET_ARTICLES
export const setArticles = articles => ({
type: 'SET_ARTICLES',
articles
});
export const startSetArticles = () => {
return dispatch => {
return database.ref('articles').once('value').then(snapshot => {
const articles = [];
snapshot.forEach(a => {
articles.push({
id: a.key,
...a.val()
});
});
dispatch(setArticles(articles));
});
};
};
我的减速机reducers/articles.js
:
const articlesReducerDefaultState = [];
export default (state = articlesReducerDefaultState, action) => {
switch (action.type) {
case 'SET_ARTICLES':
return action.articles;
default:
return state;
}
};
但我不能让它工作。这是console.log(props.articles)
组件的控制台输出:
ƒ articles() {
return dispatch((0, _articles.startSetArticles)());
}
任何想法 ?它应该呈现两个帖子,但它只返回函数本身。(我从三元运算符那里得到“无文章”)
解决方案
articles
是一个函数,因为这正是你所做的:
const mapDispatchToProps = dispatch => ({
articles: () => dispatch(startSetArticles())
});
你将 dispatch映射到 props 并将它映射到一个调用的 prop articles
,它是一个调度动作的函数。这里没有惊喜。但我想您还想要将状态映射到道具,您可以使用 connect 的第一个参数来执行此操作:
const mapStateToProps = state => ({ articlesList: state.articles });
export default connect(mapStateToProps, mapDispatchToProps)(ArticlesPage);
现在,如果你这样做console.log(props)
,你应该得到具有两个属性的 Object:
{
articles, // a function from mapDispatchToProps
articlesList // a function from mapStateToProps
}
编辑:
但是,您仍然需要调用您的文章函数来使用 firebase 获取数据并填充 redux 存储。启动异步数据的最佳方法是使用 componentDidMount() 钩子:
class ArticlesPage extends React.Component {
componentDidMount() {
this.props.articles(); // use mapped function to dispatch redux action
}
render() {
// render data with array from the store
return (
<div className="articles-wrapper">
<div className="container">
{this.props.articlesList.length === 0 ? (
<p>No article</p>
) : (
this.props.articlesList.map(a => {
return <Article key={a.id} {...a} />;
})
)}
</div>
</div>
);
}
}
推荐阅读
- dynamics-crm - 从 Microsoft Flow 中的营销列表 (Dynamics CRM) 中获取所有联系人
- vue.js - 如何在 nuxt 页面 validate() 中访问当前实例?
- javascript - 将服务器端数据共享到 JS 文件
- c# - 检查要归档的 pdf 内容以发现 pdf 受密码保护
- excel - 根据 A 列数据将不同数量的 B 列单元格中的数据转换为单个逗号分隔的行
- javascript - VueJS忽略全局导入
- rust - 如何返回 &str 的向量?
- javascript - 在 React 中作为道具传递时区分 img 和 svg
- ruby-on-rails - 将 Rails 应用程序从 2 升级到 5 - 卸载模型逻辑
- spring - Thymeleaf 绑定表中的选定值