我不是百分之百确定它是否正常工作,但是它确实给出了我所遵循的视频课程的结果。
renderPosts
只是假设要呈现列表,而是第一次得到一个空白数组。当第二次调用mapStateToProps
时,数组将填充预期的值。
就好像第一次调用mapStateToProps
一样,它没有先通过动作创建者或其他东西。
COMPONENT
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { fetchPosts } from '../actions/index';
import { Link } from 'react-router';
class PostsIndex extends Component {
componentWillMount() {
console.log("componentWillMount");
this.props.fetchPosts();
}
renderPosts() {
// console.log("renderPosts - this.props.posts",this.props.posts);
if(this.props.posts){
return this.props.posts.map((post) => {
return (
<li className="list-group-itme" key="{post.id}">
<span className="pull-xs-right">{post.catagories}</span>
<strong>{post.title}</strong>
</li>
);
});
}
}
render() {
return (
<div>
<div className="text-xs-right">
<Link to="/posts/new" className="btn btn-primary">
Add New Post
</Link>
</div>
<h3>Posts</h3>
<ul className="list-group">
{this.renderPosts()}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
console.log("mapStateToProps",state.posts);
return {posts: state.posts.all}
}
export default connect(mapStateToProps, {fetchPosts})(PostsIndex);
ACTION
import axios from 'axios';
export const FETCH_POSTS = 'FETCH_POSTS';
export const CREATE_POST = 'CREATE_POST';
const ROOT_URL = 'http://reduxblog.herokuapp.com/api';
const API_KEY = '?key=qwerty123';
export function fetchPosts(){
const request = axios.get(`${ROOT_URL}/posts${API_KEY}`);
return {
type: FETCH_POSTS,
payload: request
};
}
export function createPost(props) {
const request = axios.post(`${ROOT_URL}/posts${API_KEY}`, props);
return{
type: CREATE_POST,
payload: request
}
}
REDUCER
import { FETCH_POSTS } from '../actions/index';
const INITIAL_STATE = { postsList:[], post:null };
export default function(state = INITIAL_STATE, action){
console.log("action.type",action.type);
switch (action.type) {
case FETCH_POSTS:
return {...state, postsList: action.payload.data};
default:
return state;
}
}
mapStateToProps被调用两次。在初始调用时,数组为空。在第二个电话中,我在阵列中有十个帖子。
问题是它似乎想渲染第一个数组并忽略第二个
我在
中放了一个consol.logrenderPosts 和
mapStateToProps 它呈现如下。
任何想法?
答案 0 :(得分:0)
我认为错误来自您处理Promise的方式。第一次在控制台中看到mapStateToProps时,您可以看到没有数据,所以这是PENDING,第二次是它完成了.FILFILLED。你需要找到一种方法来解决这个问题。
示例但不是最好的,我想如果声明,你可以改变你。
function loadFile(filePath){
var arrLines = [];
fs.stat(filePath, function(err, stat) {
if(err == null) {
arrLines = fsReadFileSynchToArray(filePath);
} else if(err.code == 'ENOENT') {
console.log('error: loading file ' + filePath + ' not found');
} else {
console.log('error: loading file', err.code);
}
});
return arrLines;
}
第二个应该是改变你做出承诺的方式。一个好的图书馆是redux-promise-middleware
这是我的应用程序的一个例子。
操作
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { fetchPosts } from '../actions/index';
import { Link } from 'react-router';
class PostsIndex extends Component {
componentWillMount() {
console.log("componentWillMount");
this.props.fetchPosts();
}
renderPosts() {
return this.props.posts.map((post) => {
return (
<li className="list-group-itme" key="{post.id}">
<span className="pull-xs-right">{post.catagories}</span>
<strong>{post.title}</strong>
</li>
);
});
}
render() {
return (
<div>
<div className="text-xs-right">
<Link to="/posts/new" className="btn btn-primary">
Add New Post
</Link>
</div>
<h3>Posts</h3>
<ul className="list-group">
{this.props.posts !== [] this.renderPosts() : <h1>Loading...</h1>}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
console.log("mapStateToProps",state.posts);
return {posts: state.posts.all}
}
export default connect(mapStateToProps, {fetchPosts})(PostsIndex);
减速
export const reqAllGames = games => {
const promise = new Promise((resolve, reject) => {
request
.get(`${config.ROOT_URL}/${config.API_KEY}`)
.end((err, res) => {
if (err) {
reject(err);
} else {
resolve(res.body.top);
}
});
});
return {
type: types.RECEIVE_ALL_GAMES,
payload: promise
};
};
组件
import * as types from "../constants/";
const gameReducer = (games = { isFetched: false }, action) => {
switch (action.type) {
case `${types.RECEIVE_ALL_GAMES}_PENDING`:
return {};
case `${types.RECEIVE_ALL_GAMES}_FULFILLED`:
return {
games: action.payload,
err: null,
isFetched: true
};
case `${types.RECEIVE_ALL_GAMES}_REJECTED`:
return {
games: null,
err: action.payload,
isFetched: true
};
default:
return games;
}
};
export default gameReducer;
如果您使用react-router,您可以使用onEnter api并在此处执行操作。有了这个你就知道你的组件会得到帖子。 RallyCoding https://www.youtube.com/watch?v=JicUNpwLzLY
是一个很好的教程希望能帮到你
答案 1 :(得分:0)
https://www.udemy.com/react-redux/learn/v4/questions/1693796
在您的reducer中,您将帖子列表分配给键postsList
。
case FETCH_POSTS:
return {...state, postsList: action.payload.data};
我们可以通过查看屏幕截图中的postsList
控制台日志来确认它们是否正确地被假定为mapStateToProps
。
但是,mapStateToProps
正在查看属性state.posts.all
return {posts: state.posts.all}
帖子列表未分配给all
属性,它们被分配到postsList
属性。这就是您没有在组件中看到更新的帖子列表的原因。您需要更新reducer放置帖子列表的属性,或更新您的mapStateToProps
以从正确的属性中提取帖子列表。
-Stephen Grider